- 数组的排序
sort()
方法排序问题。
sort()方法是Array原型链上自带的方法。 默认排序顺序是根据字符串Unicode码点。
// sort 排序
let arr=[12,2,34,8,7,9,15]
console.log(arr.sort()) // [12, 15, 2, 34, 7, 8, 9]
sort排序默认排序顺序是根据字符串Unicode码点来排序的。 在进行数组排序的时候经常不是我们想要的结果。
为此需要对sort()排序做一下修改。
// sort 排序改进版,适用于数组元素全是Number类型的排序
function sortNumber(a,b){
return a-b
}
let arr=[12,2,34,8,7,9,15]
let arrAfterSort=arr.sort(sortNumber)
console.log(arrAfterSort) // [2, 7, 8, 9, 12, 15, 34]
上面的方法正确的做出了数组中按照从小到大的顺序进行排序。
如果需要从大到小排序,只需要将 sortNumber中改为b-a即可
语法
arr.sort([compareFunction])
参数
那个参数是指按照何种方式进行排序,如果参数为空,那就按照默认的unicode的方式进行排序。 就是最开始看到的那种排序方式。
返回值
排序后的数组。请注意,数组已原地排序,并且不进行复制。
描述
如果没有指明 compareFunction ,那么元素会按照转换为的字符串的诸个字符的Unicode位点进行排序。例如 "
Banana
" 会被排列到 "cherry
" 之前。当数字按由小到大排序时,9 出现在 80 之前,但因为(没有指明 compareFunction),比较的数字会先被转换为字符串,所以在Unicode顺序上 "80" 要比 "9" 要靠前
。
如果指明了 compareFunction ,那么数组会按照调用该函数的返回值排序。即 a 和 b 是两个将要被比较的元素:
如果 compareFunction(a, b) 小于 0 ,那么 a 会被排列到 b 之前;
如果 compareFunction(a, b) 等于 0 , a 和 b 的相对位置不变。
如果 compareFunction(a, b) 大于 0 , b 会被排列到 a 之前。
compareFunction(a, b) 必须总是对相同的输入返回相同的比较结果,否则排序的结果将是不确定的。
上面排序一个元素全是Number类型的数组时候,可以使用函数表达式,更为方便。
代码如下:
// sort 排序改进版,函数表达式
let arr=[12,2,34,8,7,9,15]
arr.sort((a,b)=>a-b)
console.log(arr) // [2, 7, 8, 9, 12, 15, 34]
2.数组中按照对象的某个属性进行排序
方法如下
let goods=[
{name: 'apple',price: 21},
{name: 'huawei',price: 12},
{name: 'samsung',price: 7},
{name: 'xiaomi', price: 16}
]
let goodsAfterSort=goods.sort((a,b)=>a.price-b.price)
console.log(goodsAfterSort)
上面就实现了数组元素中按照价格从低到高的顺序进行排序。
按照name进行排序
代码如下
let goods=[
{name: 'apple',price: 21},
{name: 'samsung',price: 7},
{name: 'huawei',price: 12},
{name: 'xiaomi', price: 16}
]
let goodsAfterSort=goods.sort((a,b)=>{
var nameA=a.name.toUpperCase()
var nameB=b.name.toUpperCase()
if(nameA<nameB){
return -1
}
if(nameA>nameB){
return 1
}
return 0;
})
console.log(goodsAfterSort)
3.数组元素的增删改查
splice方法
语法
arrayObject.splice(index,deleteCount,item1,.....,itemX)
splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目。
参数
index
必须
指定修改的开始位置(从0计数)。如果超出了数组的长度,则从数组末尾开始添加内容;如果是负值,则表示从数组末位开始的第几位(从-1计数);如果负数的绝对值大于数组的长度,则表示开始位置为第0位。
howmany
整数,表示要移除的数组元素的个数。
如果 deleteCount 是 0或者负数,则不移除元素。这种情况下,至少应添加一个新元素。
如果 deleteCount 大于start 之后的元素的总数,则从 start 后面的元素都将被删除(含第 start 位)。
如果deleteCount被省略,则其相当于(arr.length - start)。
item1, ..., itemX
要添加进数组的元素,从start 位置开始。如果不指定,则 splice() 将只删除数组元素。
splice方法使用deleteCount参数来控制是删除还是添加:
start参数是必须的,表示开始的位置
返回值
由被删除的元素组成的一个数组。如果只删除了一个元素,则返回只包含一个元素的数组。如果没有删除元素,则返回空数组。
测试如下:
// splice方法的使用
let arr=[1,2,3,4,5,6]
arr.splice(0,1)
console.log(arr) // [2,3,4,5,6]
可以看到arr变了,变成了经过splice后的数组。
// splice方法的返回值
let arr=[1,2,3,4,5,6]
let t=arr.splice(0,1)
console.log(t) // [1]
splice方法的返回值是被切掉元素组成的数组。
// splice方法删除并添加元素
let arr=[1,2,3,4,5,6]
arr.splice(2,1,'a','b')
console.log(arr) // [1, 2, "a", "b", 4, 5, 6]
从数组index为2的位置开始删除,删除1个元素。 并从这里塞进去2个新元素,arr变成了新数组
// splice方法删除并添加元素
let arr=[1,2,3,4,5,6]
let t=arr.splice(2,1,'a','b')
console.log(t) // [3]
splice函数的返回值始终是被切掉元素组成的数组。
start参数为负数的情况。
// index为负数的情况
let arr=[1,2,3,4,5,6]
arr.splice(-2,2)
console.log(arr) // [1,2,3,4]
表示从倒数第2个开始删除,删除2个,arr就变成了[1,2,3,4]
start参数为负数,且绝对值大于数组长度
// start参数为负数,且绝对值大于数组长度
let arr=[1,2,3,4,5,6]
arr.splice(-8,2)
console.log(arr) // [3, 4, 5, 6]
start参数为负数,且绝对值大于数组长度时,则start相当于0
start参数为负数,且新增元素。
// start参数为负数,且绝对值大于数组长度
let arr=[1,2,3,4,5,6]
arr.splice(-3,2,'c','d')
console.log(arr) // [1, 2, 3, "c", "d", 6]
上面表示从倒数第3个开始删除,删除2个元素,并且从倒数第3个位置新增2个元素c和d
slice方法
slice方法是定义在Array原型链上的方法。
Array.prototype.hasOwnProperty('slice')
// true
slice() 方法返回一个新的数组对象,这一对象是一个由 begin和 end(不包括end)决定的原数组的浅拷贝。原始数组不会被改变。
语法
arr.slice()
arr.slice(begin)
arr.slice(begin, end)
参数
begin
可选
从该索引处开始提取原数组中的元素(从0开始)。
end
可选
在该索引处结束提取原数组元素(从0开始)。slice会提取原数组中索引从 begin 到 end 的所有元素(包含begin,但不包含end)。
slice(1,4) 提取原数组中的第二个元素开始直到第四个元素的所有元素 (索引为 1, 2, 3的元素)。
如果该参数为负数, 则它表示在原数组中的倒数第几个元素结束抽取。 slice(-2,-1)表示抽取了原数组中的倒数第二个元素到最后一个元素(不包含最后一个元素,也就是只有倒数第二个元素)。
如果 end 被省略,则slice 会一直提取到原数组末尾。
如果 end 大于数组长度,slice 也会一直提取到原数组末尾。
返回值
一个含有提取元素的新数组
例子:
// 数组中的slice方法
let arr=[1,2,3,4,5,6,7,8]
arr.slice(2,3)
console.log(arr) // [1,2,3,4,5,6,7,8]
可以看到经过slice后原数组不变
// 数组中的slice方法的返回值
let arr=[1,2,3,4,5,6,7,8]
let t=arr.slice(2,3)
console.log(t) // [3]
slice方法函数的返回值是一个新数组,含有提取元素的新数组。
本例中从index为2开始提取,提取到index为3,前面提到包含start但是不包含end,所以只提取了index为2的这一个元素
slice方法不会改变原数组
isArray
Array.isArray()用于确定传递的值是否是一个 Array
该方法是定义在Array对象上面的,不是定义在其原型链上的。
Array.hasOwnProperty('isArray')
// true
Array.prototype.hasOwnProperty('isArray')
// false
例子
Array.isArray([1,2,3]) // true
Array.isArray({foo: '123'}) // false
Array.isArray("foobar") // false
Array.isArray(undefined) // false
Array.isArray(Array) // false
Array.isArray(Array.prototype) // true
鲜为人知的事实:其实 Array.prototype 也是一个数组。
当检测Array实例时, Array.isArray 优于 instanceof,因为Array.isArray能检测iframes
下面的函数调用都返回 true
Array.isArray([]); // true
Array.isArray([1]); // true
Array.isArray(new Array()); // true
下面的函数调用都返回 false
Array.isArray(); // false
Array.isArray({}); // false
Array.isArray(null); // false
Array.isArray(undefined); // false
Array.isArray(17); // false
Array.isArray('Array'); // false
Array.isArray(true); // false
Array.isArray(false); // false
Array.isArray({ __proto__: Array.prototype }); // false
Array.from
Array.from() 方法从一个类似数组或可迭代对象中创建一个新的数组实例
var str='javascript'
Array.from(str) // ["j", "a", "v", "a", "s", "c", "r", "i", "p", "t"]
...扩展运算符也能实现类似的功能
var str='javascript'
[...str] // ["j", "a", "v", "a", "s", "c", "r", "i", "p", "t"]
语法
Array.from(arrayLike[, mapFn[, thisArg]])
第二个参数是回调函数,新数组中的每个元素会执行该回调函数。
var str='javascript'
Array.from(str,item=>item+1) // ["j1", "a1", "v1", "a1", "s1", "c1", "r1", "i1", "p1", "t1"]
返回值
一个新的数组实例
Array.of
方法创建一个具有可变数量参数的新数组实例,而不考虑参数的数量或类型
Array.of() 和 Array 构造函数之间的区别在于处理整数参数:
Array.of(7) 创建一个具有单个元素 7 的数组
,
而 Array(7) 创建一个长度为7的空数组
Array.of(7); // [7]
Array.of(1, 2, 3); // [1, 2, 3]
Array(7); // [ , , , , , , ]
Array(1, 2, 3); // [1, 2, 3]
concat
concat() 方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组
var array1 = ['a', 'b', 'c'];
var array2 = ['d', 'e', 'f'];
console.log(array1.concat(array2)); // ["a", "b", "c", "d", "e", "f"]
语法
var new_array = old_array.concat(value1[, value2[, ...[, valueN]]])
参数
valueN
将数组和/或值连接成新数组
新的 Array
实例。
描述
concat
方法创建一个新的数组,它由被调用的对象中的元素组成,每个参数的顺序依次是该参数的元素(如果参数是数组)或参数本身(如果参数不是数组)。它不会递归到嵌套数组参数中。
concat
方法不会改变this
或任何作为参数提供的数组,而是返回一个浅拷贝,它包含与原始数组相结合的相同元素的副本。 原始数组的元素将复制到新数组中,如下所示:
对象引用(而不是实际对象):
concat
将对象引用复制到新数组中。 原始数组和新数组都引用相同的对象。 也就是说,如果引用的对象被修改,则更改对于新数组和原始数组都是可见的。 这包括也是数组的数组参数的元素。数据类型如字符串,数字和布尔(不是
String
,Number
和Boolean
对象):concat
将字符串和数字的值复制到新数组中。
例子
连接两个数组
var alpha = ['a', 'b', 'c'];
var numeric = [1, 2, 3];
alpha.concat(numeric);
// result in ['a', 'b', 'c', 1, 2, 3]
var num1 = [1, 2, 3],
num2 = [4, 5, 6],
num3 = [7, 8, 9];
var nums = num1.concat(num2, num3);
console.log(nums);
// results in [1, 2, 3, 4, 5, 6, 7, 8, 9]
以下代码将三个值连接到数组
var alpha = ['a', 'b', 'c'];
var alphaNumeric = alpha.concat(1, [2, 3]);
console.log(alphaNumeric);
// results in ['a', 'b', 'c', 1, 2, 3]
var num1 = [[1]];
var num2 = [2, [3]];
var nums = num1.concat(num2);
console.log(nums);
// results in [[1], 2, [3]]
// modify the first element of num1
num1[0].push(4);
console.log(nums);
// results in [[1, 4], 2, [3]]
copyWithin()
方法浅复制数组的一部分到同一数组中的另一个位置,并返回它,而不修改其大小。
var array1 = [1, 2, 3, 4, 5];
// place at position 0 the element between position 3 and 4
console.log(array1.copyWithin(0, 3, 4));
// expected output: Array [4, 2, 3, 4, 5]
// place at position 1 the elements after position 3
console.log(array1.copyWithin(1, 3));
// expected output: Array [4, 4, 5, 4, 5]
上面的例子是说,从索引值为3的位置开始复制,复制到索引值为4的位置。 因为不包含end,所以实际上只复制了一个元素那就是索引值为3的,然后把它替换到target为0的位置,所以可以看到用4替换了数组第一个元素1,最后返回的结果是[4, 2, 3, 4, 5]
语法
arr.copyWithin(target[, start[, end]])
target
0 为基底的索引,复制序列到该位置。如果是负数,target 将从末尾开始计算。
如果 target 大于等于 arr.length,将会不发生拷贝。如果 target 在 start 之后,复制的序列将被修改以符合 arr.length。
start
0 为基底的索引,开始复制元素的起始位置。如果是负数,start 将从末尾开始计算。
如果 start 被忽略,copyWithin 将会从0开始复制。
end
0 为基底的索引,开始复制元素的结束位置。copyWithin 将会拷贝到该位置,但不包括 end 这个位置的元素。如果是负数, end 将从末尾开始计算。
如果 end 被忽略,copyWithin 将会复制到 arr.length。
改变了的数组
该方法会改变原始数组,会变成改变后的数组。
var arr=[1,2,3,4,5,6]
arr.copyWithin(0,3,4)
console.log(arr) // [4, 2, 3, 4, 5, 6]
entries()
entries() 方法返回一个新的Array Iterator对象,该对象包含数组中每个索引的键/值对。
var arr=['a','b','c']
var t=arr.entries()
console.log(t) // Array Iterator {}
返回值是一个Array Iterator对象
Iterator对象都有next()方法
console.log(t.next()) // {value: Array(2), done: false}
console.log(t.next().value) // [1, "b"]
console.log(t.next().value) // [2, "c"]
语法
arr.entries()
返回值
一个新的
Array
迭代器对象。
例子:
1、 Array Iterator
var arr = ["a", "b", "c"];
var iterator = arr.entries();
console.log(iterator);
/*Array Iterator {}
__proto__:Array Iterator
next:ƒ next()
Symbol(Symbol.toStringTag):"Array Iterator"
__proto__:Object
*/
2、iterator.next()
var arr = ["a", "b", "c"];
var iterator = arr.entries();
console.log(iterator.next());
/*{value: Array(2), done: false}
done:false
value:(2) [0, "a"]
__proto__: Object
*/
// iterator.next()返回一个对象,对于有元素的数组,
// 是next{ value: Array(2), done: false };
// next.done 用于指示迭代器是否完成:在每次迭代时进行更新而且都是false,
// 直到迭代器结束done才是true。
// next.value是一个["key":"value"]的数组,是返回的迭代器中的元素值。
3、iterator.next方法运行
var arr = ["a", "b", "c"];
var iter = arr.entries();
var a = [];
// for(var i=0; i< arr.length; i++){ // 实际使用的是这个
for(var i=0; i< arr.length+1; i++){ // 注意,是length+1,比数组的长度大
var tem = iter.next(); // 每次迭代时更新next
console.log(tem.done); // 这里可以看到更新后的done都是false
if(tem.done !== true){ // 遍历迭代器结束done才是true
console.log(tem.value);
a[i]=tem.value;
}
}
console.log(a); // 遍历完毕,输出next.value的数组
4、二维数组按行排序
function sortArr(arr) {
var goNext = true;
var entries = arr.entries();
while (goNext) {
var result = entries.next();
if (result.done !== true) {
result.value[1].sort((a, b) => a - b);
goNext = true;
} else {
goNext = false;
}
}
return arr;
}
var arr = [[1,34],[456,2,3,44,234],[4567,1,4,5,6],[34,78,23,1]];
sortArr(arr);
/*(4) [Array(2), Array(5), Array(5), Array(4)]
0:(2) [1, 34]
1:(5) [2, 3, 44, 234, 456]
2:(5) [1, 4, 5, 6, 4567]
3:(4) [1, 23, 34, 78]
length:4
__proto__:Array(0)
*/
5、使用for…of 循环
var arr = ["a", "b", "c"];
var iterator = arr.entries();
// undefined
for (let e of iterator) {
console.log(e);
}
// [0, "a"]
// [1, "b"]
// [2, "c"]
every()
every() 方法测试数组的所有元素是否都通过了指定函数的测试。
function isBelowThreshold(currentValue) {
return currentValue < 40;
}
var array1 = [1, 30, 39, 29, 10, 13];
console.log(array1.every(isBelowThreshold)); // true
语法
arr.every(callback[, thisArg])
参数
callback 用来测试每个元素的函数。
thisArg 执行 callback 时使用的 this 值
描述
every 方法为数组中的每个元素执行一次 callback 函数,直到它找到一个使 callback 返回 false(表示可转换为布尔值 false 的值)的元素。如果发现了一个这样的元素,every 方法将会立即返回 false。否则,callback 为每一个元素返回 true,every 就会返回 true。callback 只会为那些已经被赋值的索引调用。不会为那些被删除或从来没被赋值的索引调用。
callback 被调用时传入三个参数:元素值,元素的索引,原数组。
如果为 every 提供一个 thisArg 参数,则该参数为调用 callback 时的 this 值。如果省略该参数,则 callback 被调用时的 this 值,在非严格模式下为全局对象,在严格模式下传入 undefined。
every 不会改变原数组。
every 遍历的元素范围在第一次调用 callback 之前就已确定了。在调用 every 之后添加到数组中的元素不会被 callback 访问到。如果数组中存在的元素被更改,则他们传入 callback 的值是 every 访问到他们那一刻的值。那些被删除的元素或从来未被赋值的元素将不会被访问到。
every 和数学中的"所有"类似,当所有的元素都符合条件才返回true。另外,空数组也是返回true。(空数组中所有元素都符合给定的条件,注:因为空数组没有元素)。
例子:
检测数组元素是否都大于10
var arr=[5,8,12,34,1,7]
arr.every(item=>item>10) // false
fill
fill() 方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。
var array1 = [1, 2, 3, 4];
// fill with 0 from position 2 until position 4
console.log(array1.fill(0, 2, 4));
// expected output: [1, 2, 0, 0]
// fill with 5 from position 1
console.log(array1.fill(5, 1));
// expected output: [1, 5, 5, 5]
console.log(array1.fill(6));
// expected output: [6, 6, 6, 6]
语法
arr.fill(value[, start[, end]])
参数
value
用来填充数组元素的值
start
起始索引,默认值为0
end
终止索引,默认值为 this.length
返回值
修改后的数组。
描述
fill 方法接受三个参数 value, start 以及 end. start 和 end 参数是可选的, 其默认值分别为 0 和 this 对象的 length 属性值。
如果 start 是个负数, 则开始索引会被自动计算成为 length+start, 其中 length 是 this 对象的 length 属性值。如果 end 是个负数, 则结束索引会被自动计算成为 length+end。
fill 方法故意被设计成通用方法, 该方法不要求 this 是数组对象。
fill 方法是个可变方法, 它会改变调用它的 this 对象本身, 然后返回它, 而并不是返回一个副本。
当一个对象被传递给 fill方法的时候, 填充数组的是这个对象的引用。
例子:
[1, 2, 3].fill(4); // [4, 4, 4]
[1, 2, 3].fill(4, 1); // [1, 4, 4]
[1, 2, 3].fill(4, 1, 2); // [1, 4, 3]
[1, 2, 3].fill(4, 1, 1); // [1, 2, 3]
[1, 2, 3].fill(4, 3, 3); // [1, 2, 3]
[1, 2, 3].fill(4, -3, -2); // [4, 2, 3]
[1, 2, 3].fill(4, NaN, NaN); // [1, 2, 3]
[1, 2, 3].fill(4, 3, 5); // [1, 2, 3]
Array(3).fill(4); // [4, 4, 4]
[].fill.call({ length: 3 }, 4); // {0: 4, 1: 4, 2: 4, length: 3}
// Objects by reference.
var arr = Array(3).fill({}) // [{}, {}, {}];
arr[0].hi = "hi"; // [{ hi: "hi" }, { hi: "hi" }, { hi: "hi" }]
filter
filter() 方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素
var words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];
const result = words.filter(word => word.length > 6);
console.log(result);
// expected output: Array ["exuberant", "destruction", "present"]
语法
var new_array = arr.filter(callback(element[, index[, array]])[, thisArg])
参数
callback
用来测试数组的每个元素的函数。调用时使用参数 (element, index, array)。
返回true表示保留该元素(通过测试),false则不保留。它接受三个参数:
element
当前在数组中处理的元素
index
可选 正在处理元素在数组中的索引
array
可选 调用了filter的数组
thisArg
可选 执行 callback 时的用于 this 的值
返回值
一个新的通过测试的元素的集合的数组,如果没有通过测试则返回空数组
描述
filter
为数组中的每个元素调用一次 callback
函数,并利用所有使得 callback
返回 true 或 等价于 true 的值 的元素创建一个新数组。callback
只会在已经赋值的索引上被调用,对于那些已经被删除或者从未被赋值的索引不会被调用。那些没有通过 callback
测试的元素会被跳过,不会被包含在新数组中。
callback
被调用时传入三个参数:
- 元素的值
- 元素的索引
- 被遍历的数组
如果为 filter
提供一个 thisArg
参数,则它会被作为 callback
被调用时的 this
值。否则,callback
的 this
值在非严格模式下将是全局对象,严格模式下为 undefined
。
callback
最终观察到的this
值是根据通常函数所看到的 "this"的规则确定的。
filter
不会改变原数组,它返回过滤后的新数组。
filter
遍历的元素范围在第一次调用 callback
之前就已经确定了。在调用 filter
之后被添加到数组中的元素不会被 filter
遍历到。如果已经存在的元素被改变了,则他们传入 callback
的值是 filter
遍历到它们那一刻的值。被删除或从来未被赋值的元素不会被遍历到。
例子:
var filtered = [12, 5, 8, 130, 44].filter(item=>item>=10); // [12, 130, 44]
在数组中搜索
var fruits = ['apple', 'banana', 'grapes', 'mango', 'orange'];
/**
* Array filters items based on search criteria (query)
*/
function filterItems(query) {
return fruits.filter(function(el) {
return el.toLowerCase().indexOf(query.toLowerCase()) > -1;
})
}
console.log(filterItems('ap')); // ['apple', 'grapes']
console.log(filterItems('an')); // ['banana', 'mango', 'orange']
find
find() 方法返回数组中满足提供的测试函数的第一个元素的值
var array1 = [5, 12, 8, 130, 44];
var found = array1.find(function(element) {
return element > 10;
});
console.log(found);
// expected output: 12
语法
arr.find(callback[, thisArg])
参数
callback
在数组每一项上执行的函数,接收 3 个参数:
element
当前遍历到的元素
index
当前遍历到的索引
array
数组本身
thisArg
(可选)
指定 callback 的 this 参数
返回值
当某个元素通过 callback 的测试时,返回数组中的一个值,否则返回 undefined
描述
find 方法对数组中的每一项元素执行一次 callback
函数,直至有一个 callback 返回 true
。当找到了这样一个元素后,该方法会立即返回这个元素的值,否则返回 undefined
。注意 callback
函数会为数组中的每个索引调用即从 0
到 length - 1
,而不仅仅是那些被赋值的索引,这意味着对于稀疏数组来说,该方法的效率要低于那些只遍历有值的索引的方法。
callback 函数带有3个参数:当前元素的值、当前元素的索引,以及数组本身。
如果提供了 thisArg 参数,那么它将作为每次 callback 函数执行时的上下文对象,否则上下文对象为 undefined
。
find 方法不会改变数组。
在第一次调用 callback
函数时会确定元素的索引范围,因此在 find
方法开始执行之后添加到数组的新元素将不会被 callback 函数访问到。如果数组中一个尚未被callback函数访问到的元素的值被callback函数所改变,那么当callback函数访问到它时,它的值是将是根据它在数组中的索引所访问到的当前值。被删除的元素仍旧会被访问到。
示例
用对象的属性查找数组里的对象
var inventory = [
{name: 'apples', quantity: 2},
{name: 'bananas', quantity: 0},
{name: 'cherries', quantity: 5}
];
function findCherries(fruit) {
return fruit.name === 'cherries';
}
console.log(inventory.find(findCherries)); // { name: 'cherries', quantity: 5 }
寻找数组中的质数
function isPrime(element, index, array) {
var start = 2;
while (start <= Math.sqrt(element)) {
if (element % start++ < 1) {
return false;
}
}
return element > 1;
}
console.log([4, 6, 8, 12].find(isPrime)); // undefined, not found
console.log([4, 5, 8, 12].find(isPrime)); // 5
findIndex
findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引。否则返回-1。
var array1 = [5, 12, 8, 130, 44];
function findFirstLargeNumber(element) {
return element > 13;
}
console.log(array1.findIndex(findFirstLargeNumber));
// expected output: 3
语法
arr.findIndex(callback[, thisArg])
参数
callback
针对数组中的每个元素, 都会执行该回调函数, 执行时会自动传入下面三个参数:
element
当前的元素。
index
当前元素的索引。
array
调用findIndex的数组
thisArg
可选。执行callback时作为this对象的值
描述
findIndex
方法对数组中的每个数组索引0..length-1
(包括)执行一次callback
函数,直到找到一个callback
函数返回真实值(强制为true
)的值。如果找到这样的元素,findIndex
会立即返回该元素的索引。如果回调从不返回真值,或者数组的length
为0,则findIndex
返回-1。 与某些其他数组方法(如Array#some)不同,在稀疏数组中,即使对于数组中不存在的条目的索引也会调用回调函数。
回调函数调用时有三个参数:元素的值,元素的索引,以及被遍历的数组。
如果一个 thisArg
参数被提供给 findIndex
, 它将会被当作this
使用在每次回调函数被调用的时候。如果没有被提供,将会使用undefined
。
findIndex
不会修改所调用的数组。
在第一次调用callback
函数时会确定元素的索引范围,因此在findIndex
方法开始执行之后添加到数组的新元素将不会被callback
函数访问到。如果数组中一个尚未被callback
函数访问到的元素的值被callback
函数所改变,那么当callback
函数访问到它时,它的值是将是根据它在数组中的索引所访问到的当前值。被删除的元素仍然会被访问到。
示例
以下示例查找数组中素数的元素的索引(如果不存在素数,则返回-1)
function isPrime(element, index, array) {
var start = 2;
while (start <= Math.sqrt(element)) {
if (element % start++ < 1) {
return false;
}
}
return element > 1;
}
console.log([4, 6, 8, 12].findIndex(isPrime)); // -1, not found
console.log([4, 6, 7, 12].findIndex(isPrime)); // 2
flat
flat() 方法会递归到指定深度将所有子数组连接,并返回一个新数组
// 数组中的flat方法的
var arr1=[1,2,[3],[4]]
arr1.flat()
console.log(arr1.flat()) // [1, 2, 3, 4]
语法
var newArray = arr.flat(depth)
示例
扁平化数组
var arr1 = [1, 2, [3, 4]];
arr1.flat();
// [1, 2, 3, 4]
var arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]
var arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2);
// [1, 2, 3, 4, 5, 6]
扁平化与空项
flat()方法会移除数组中的空项
var arr4 = [1, 2, , 4, 5];
arr4.flat();
// [1, 2, 4, 5]
forEach
forEach() 方法对数组的每个元素执行一次提供的函数
var array1 = ['a', 'b', 'c'];
array1.forEach(function(element) {
console.log(element);
});
// expected output: "a"
// expected output: "b"
// expected output: "c"
语法
array.forEach(callback(currentValue, index, array){
//do something
}, this)
array.forEach(callback[, thisArg])
参数
callback
为数组中每个元素执行的函数,该函数接收三个参数:
currentValue
数组中正在处理的当前元素
index
(可选) 数组中正在处理的当前元素的索引
array
可选 forEach()方法正在操作的数组
thisArg
(可选)
返回值
undefined
描述
forEach
方法按升序为数组中含有效值的每一项执行一次callback
函数,那些已删除或者未初始化的项将被跳过(例如在稀疏数组上)。
callback
函数会被依次传入三个参数:
- 数组当前项的值
- 数组当前项的索引
- 数组对象本身
如果给forEach传递了thisArg
参数,当调用时,它将被传给callback
函数,作为它的this值。否则,将会传入 undefined
作为它的this值。callback函数最终可观察到this值,这取决于 函数观察到this
的常用规则。
forEach
遍历的范围在第一次调用 callback
前就会确定。调用forEach
后添加到数组中的项不会被 callback
访问到。如果已经存在的值被改变,则传递给 callback
的值是 forEach
遍历到他们那一刻的值。已删除的项不会被遍历到。如果已访问的元素在迭代时被删除了(例如使用 shift()
) ,之后的元素将被跳过 - 参见下面的示例。
forEach()
为每个数组元素执行callback函数;不像map()
或者reduce()
,它总是返回 undefined
值,并且不可链式调用。典型用例是在一个链的最后执行副作用。
includes
includes() 方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回false
var array1 = [1, 2, 3];
console.log(array1.includes(2));
// expected output: true
var pets = ['cat', 'dog', 'bat'];
console.log(pets.includes('cat'));
// expected output: true
console.log(pets.includes('at'));
// expected output: false
语法
arr.includes(searchElement)
arr.includes(searchElement, fromIndex)
参数
searchElement
需要查找的元素值
fromIndex
从该索引处开始查找 searchElement。如果为负值,则按升序从 array.length - fromIndex 的索引开始搜索。默认为 0
返回值
一个Boolean 值
示例
[1, 2, 3].includes(2); // true
[1, 2, 3].includes(4); // false
[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true
[1, 2, NaN].includes(NaN); // true
如果fromIndex 大于等于数组长度 ,则返回 false 。该数组不会被搜索
var arr = ['a', 'b', 'c'];
arr.includes('c', 3); //false
arr.includes('c', 100); // false
计算出的索引小于 0
如果 fromIndex 为负值,计算出的索引将作为开始搜索searchElement的位置。如果计算出的索引小于 0,则整个数组都会被搜索。
// 数组长度是3
// fromIndex 是 -100
// computed index 是 3 + (-100) = -97
var arr = ['a', 'b', 'c'];
arr.includes('a', -100); // true
arr.includes('b', -100); // true
arr.includes('c', -100); // true
includes() 作为一个通用方法
includes()
方法有意设计为通用方法。它不要求this
值是数组对象,所以它可以被用于其他类型的对象 (比如类数组对象)。下面的例子展示了 在函数的arguments对象上调用的includes()
方法。
(function() {
console.log([].includes.call(arguments, 'a')); // true
console.log([].includes.call(arguments, 'd')); // false
})('a','b','c');
indexOf
indexOf()方法返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1
var beasts = ['ant', 'bison', 'camel', 'duck', 'bison'];
console.log(beasts.indexOf('bison'));
// expected output: 1
// start from index 2
console.log(beasts.indexOf('bison', 2));
// expected output: 4
console.log(beasts.indexOf('giraffe'));
// expected output: -1
语法
arr.indexOf(searchElement)
arr.indexOf(searchElement[, fromIndex = 0])
参数
searchElement
要查找的元素
fromIndex
开始查找的位置。如果该索引值大于或等于数组长度,意味着不会在数组里查找,返回-1。如果参数中提供的索引值是一个负值,则将其作为数组末尾的一个抵消,即-1表示从最后一个元素开始查找,-2表示从倒数第二个元素开始查找 ,以此类推。 注意:如果参数中提供的索引值是一个负值,并不改变其查找顺序,查找顺序仍然是从前向后查询数组。如果抵消后的索引值仍小于0,则整个数组都将会被查询。其默认值为0.
返回值
首个被找到的元素在数组中的索引位置; 若没有找到则返回 -1
示例
以下例子使用indexOf方法确定多个值在数组中的位置
var array = [2, 5, 9];
array.indexOf(2); // 0
array.indexOf(7); // -1
array.indexOf(9, 2); // 2
array.indexOf(2, -1); // -1
array.indexOf(2, -3); // 0
找出指定元素出现的所有位置
var indices = [];
var array = ['a', 'b', 'a', 'c', 'a', 'd'];
var element = 'a';
var idx = array.indexOf(element);
while (idx != -1) {
indices.push(idx);
idx = array.indexOf(element, idx + 1);
}
console.log(indices);
// [0, 2, 4]
判断一个元素是否在数组里,不在则更新数组
function updateVegetablesCollection (veggies, veggie) {
if (veggies.indexOf(veggie) === -1) {
veggies.push(veggie);
console.log('New veggies collection is : ' + veggies);
} else if (veggies.indexOf(veggie) > -1) {
console.log(veggie + ' already exists in the veggies collection.');
}
}
var veggies = ['potato', 'tomato', 'chillies', 'green-pepper'];
// New veggies collection is : potato,tomato,chillies,green-papper,spinach
updateVegetablesCollection(veggies, 'spinach');
// spinach already exists in the veggies collection.
updateVegetablesCollection(veggies, 'spinach');
join
join()
方法将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。
var elements = ['Fire', 'Wind', 'Rain'];
console.log(elements.join());
// expected output: Fire,Wind,Rain
console.log(elements.join(''));
// expected output: FireWindRain
console.log(elements.join('-'));
// expected output: Fire-Wind-Rain
语法
str = arr.join()
// 默认为 ","
str = arr.join("")
// 分隔符 === 空字符串 ""
str = arr.join(separator)
// 分隔符
####### 参数
separator
指定一个字符串来分隔数组的每个元素。
如果需要(separator),将分隔符转换为字符串。
如果省略(),数组元素用逗号分隔。默认为 ","。
如果separator是空字符串(""),则所有元素之间都没有任何字符
返回值
一个所有数组元素连接的字符串。如果 arr.length 为0,则返回空字符串。
描述
所有的数组元素被转换成字符串,再用一个分隔符将这些字符串连接起来。如果元素是undefined 或者null, 则会转化成空字符串。
例子
使用四种不同的分隔符连接数组元素
下例首先创建了一个数组 a,包含有三个元素,然后用四种不同的分隔符连接所有数组元素。首先是默认的分隔符逗号,然后是一个逗号加空格,接下来是一个加号前后加空格,最后是一个空字符串
var a = ['Wind', 'Rain', 'Fire'];
var myVar1 = a.join(); // myVar1的值变为"Wind,Rain,Fire"
var myVar2 = a.join(', '); // myVar2的值变为"Wind, Rain, Fire"
var myVar3 = a.join(' + '); // myVar3的值变为"Wind + Rain + Fire"
var myVar4 = a.join(''); // myVar4的值变为"WindRainFire"
连接类数组对象
下面的示例将连接类数组对象(arguments),通过在Array.prototype.join
上调用Function.prototype.call
。
function f(a, b, c) {
var s = Array.prototype.join.call(arguments);
console.log(s); // '1,a,true'
}
f(1, 'a', true);
keys
keys() 方法返回一个包含数组中每个索引键的Array Iterator对象
var array1 = ['a', 'b', 'c'];
var iterator = array1.keys();
for (let key of iterator) {
console.log(key); // expected output: 0 1 2
}
语法
arr.keys()
返回值
一个新的 Array
迭代器对象
var arr=[1,2,4,5,6,7,8,10]
console.log(arr.keys())
// Array Iterator {}
// __proto__: Array Iterator
// next: ƒ next()
// Symbol(Symbol.toStringTag): "Array Iterator"
// __proto__: Object
示例
索引迭代器会包含那些没有对应元素的索引
var arr = ["a", , "c"];
var sparseKeys = Object.keys(arr);
var denseKeys = [...arr.keys()];
console.log(sparseKeys); // ['0', '2']
console.log(denseKeys); // [0, 1, 2]
lastIndexOf
lastIndexOf() 方法返回指定元素(也即有效的 JavaScript 值或变量)在数组中的最后一个的索引,如果不存在则返回 -1。从数组的后面向前查找,从 fromIndex 处开始。
var animals = ['Dodo', 'Tiger', 'Penguin', 'Dodo'];
console.log(animals.lastIndexOf('Dodo'));
// expected output: 3
console.log(animals.lastIndexOf('Tiger'));
// expected output: 1
语法
arr.lastIndexOf(searchElement[, fromIndex = arr.length - 1])
参数
searchElement
被查找的元素
fromIndex
从此位置开始逆向查找。默认为数组的长度减 1,即整个数组都被查找。如果该值大于或等于数组的长度,则整个数组会被查找。如果为负值,将其视为从数组末尾向前的偏移。即使该值为负,数组仍然会被从后向前查找。如果该值为负时,其绝对值大于数组长度,则方法返回 -1,即数组不会被查找
返回值
数组中最后一个元素的索引,如未找到返回-1
示例
var array = [2, 5, 9, 2];
var index = array.lastIndexOf(2);
// index is 3
index = array.lastIndexOf(7);
// index is -1
index = array.lastIndexOf(2, 3);
// index is 3
index = array.lastIndexOf(2, 2);
// index is 0
index = array.lastIndexOf(2, -2);
// index is 0
index = array.lastIndexOf(2, -1);
// index is 3
map
map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。
var array1 = [1, 4, 9, 16];
// pass a function to map
const map1 = array1.map(x => x * 2);
console.log(map1);
// expected output: Array [2, 8, 18, 32]
语法
var new_array = arr.map(function callback(currentValue[, index[, array]]) {
// Return element for new_array }[,
thisArg])
参数
callback
currentValue
callback 数组中正在处理的当前元素
index | 可选
callback 数组中正在处理的当前元素的索引。
array | 可选
callback map 方法被调用的数组。
thisArg | 可选
执行 callback 函数时使用的this 值。
返回值
一个新数组,每个元素都是回调函数的结果。
描述
map
方法会给原数组中的每个元素都按顺序调用一次 callback
函数。callback
每次执行后的返回值(包括 undefined
)组合起来形成一个新数组。 callback
函数只会在有值的索引上被调用;那些从来没被赋过值或者使用 delete
删除的索引则不会被调用。
callback
函数会被自动传入三个参数:数组元素,元素索引,原数组本身。
如果 thisArg
参数有值,则每次 callback
函数被调用的时候,this
都会指向 thisArg
参数上的这个对象。如果省略了 thisArg ``参数,``或者赋值为 null
或 undefined
,则 this 指向全局对象 。
map
不修改调用它的原数组本身(当然可以在 callback
执行时改变原数组)。
使用 map 方法处理数组时,数组元素的范围是在 callback 方法第一次调用之前就已经确定了。在 map 方法执行的过程中:原数组中新增加的元素将不会被 callback 访问到;若已经存在的元素被改变或删除了,则它们的传递到 callback 的值是 map 方法遍历到它们的那一时刻的值;而被删除的元素将不会被访问到。