JavaScript 中的数组方法

组方法中,我除了常用的 forEachmapfilter,别的每次在使用前都要上网搜索一下他们的用法,某种意义上浪费了一些时间, 遂决定开个页面,专门写这些数组方法。

先把部分 ES5 的坑填好,以后有时间再搞搞 ES5 剩余和 ES6 吧。。。

  • 实例代码采用了一些 ES6 语法
  • 所有实例代码均有测试

ES5

这里是 ES5 适用的数组方法

forEach

用函数作为循环体遍历数组中所有元素。

1
2
3
4
5
6
7
8
9
10
11
12
var arr = ['hello', ', ', 'Wrold!'];
/* item 为数组元素,cursor 为数组游标,total 为数组自身(total === arr) */
arr.forEach((item, cursor, total) => {
console.log(
`我是 ${item},` +
`我在数组里排第 ${cursor + 1} 个,` +
`这个数组是: ${JSON.stringify(total)}`
);
});

map

用函数作为循环体遍历数组中所有元素,函数返回值将会重新构建一个新的数组。

1
2
3
4
5
6
7
8
9
var arr = [5, 3, 7, 9];
/* item 为数组元素,cursor 为数组游标,total 为数组自身(total === arr) */
var square = arr.map((item, cursor, total) => {
return item * item;
});
console.log(square); /* [ 25, 9, 49, 81 ] */

every

用函数作为循环体遍历数组中所有的元素。函数返回值如果是 类false 类型的则停止循环并返回一个 false,全部遍历完则会返回一个 true

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var arr = [ 29, 12, 42 ];
/* item 为数组元素,cursor 为数组游标,total 为数组自身(total === arr) */
var result = arr.every((item, cursor, total) => {
return item % 2
});
if (result) {
console.log('可以,都是奇数');
} else {
console.log('不行,你这里面有偶数');
}

some

用函数作为循环体遍历数组中所有的元素。函数返回值如果是 类true 类型的则停止循环并返回一个 true,全部遍历完则会返回一个 false

1
2
3
4
5
6
7
8
9
10
11
var arr = [ 'marisa', 'aya' ];
/* item 为数组元素,cursor 为数组游标,total 为数组自身(total === arr) */
var result = arr.some((item, cursor, total) => item === 'aya');
if (result) {
console.log('发现 aya');
} else {
console.log('没有发现 aya');
}

filter

根据循环体函数返回值来过滤数组。用函数作为循环体遍历数组中所有元素,若函数返回 类true 类型的值则保留当前数组元素。

1
2
3
4
5
6
7
8
9
10
var arr = [2, 4, 9.99, 6, 3, 'a', 'b', {}];
/* item 为数组元素,cursor 为数组游标,total 为数组自身(total === arr) */
var integerNum = arr.filter((item, cursor, total) => {
return Number.isInteger(item);
});
console.log(integerNum); //[ 2, 4, 6, 3 ]

indexOf

以值查找数组中的元素,以游标形式返回。如果不存在则返回 -1。indexOf 方法内部采用严格相等来比较数组元素,所以,在使用复合类型数值时,必须非常小心

1
2
3
4
5
6
7
8
var obj = {};
var arr = [3, 5, 6, obj];
arr.indexOf(3); //0
arr.indexOf(88); //-1
arr.indexOf({}); //-1
arr.indexOf(obj); //3

lastIndexOf

与上述的 indexOf 相似,只不过它是由数组顶部开始查找。

1
2
3
4
var arr = [ 3, 3, 4, 3, 3 ];
console.log(arr.lastIndexOf(3)); //4

join

以参数作为分隔符。若不存在参数则采用逗号 , 表示。

1
2
3
4
5
6
var arr = [ 'C', 'Java', 'Python' ];
arr.join(); //"C,Java,Python"
arr.join(''); //"CJavaPython"

push

在数组顶部添加一个新值(堆栈压入),返回值是添加新值后的数组长度

1
2
3
4
5
6
7
8
9
var peoples = [ 'vec' ];
peoples.push('older');
peoples.push('aya');
peoples.push('t', 'o', 'r', 'z', 'o');
console.log(peoples);
//["vec", "older", "aya", "t", "o", "r", "z", "o"]

pop

在数组顶部移出一个值(堆栈推出),返回值为被移出的值,若数组为空数组,则返回值为 undefined

1
2
3
4
5
var peoples = [ 'aya', 'vec' ];
console.log(`${peoples.pop()} love ${peoples.pop()}`)
//vec love aya

reduce

从数组游标0至数组最大长度的顺序迭代数组。

1
2
3
4
5
6
7
8
9
10
11
12
13
var arr = [ 2, 8, 4, 6 ];
arr.reduce((itemA, itemB, ...a) => {
console.log(itemA, itemB, ...a);
return itemA + itemB;
});
// return value: 20
/* conole output
2 8 1 [2, 8, 4, 6]
10 4 2 [2, 8, 4, 6]
14 6 3 [2, 8, 4, 6]
*/

reduceRight

从数组最大长度至数组游标0的顺序迭代数组。

1
2
3
4
5
6
7
8
9
10
11
12
13
var arr = [ 2, 8, 4, 6 ];
arr.reduceRight((itemA, itemB, ...a) => {
console.log(itemA, itemB, ...a);
return itemA + itemB;
});
// return value: 20
/* conole output
6 4 2 [2, 8, 4, 6]
10 8 1 [2, 8, 4, 6]
18 2 0 [2, 8, 4, 6]
*/

reverse

颠倒数组顺序。

1
2
3
4
5
6
7
var strArr = 'aya evol cev'.split('');
strArr.reverse();
console.log(strArr.join(''));
//vec love aya

shift

从数组底部移出一个值。shift 方法会返回移出的值,若数组为空数组则返回 undefined

1
2
3
4
5
6
var arr = ['v', 'e'];
arr.shift(); //"v"
arr.shift(); //"e"
arr.shift(); //undefined

unshift

往数组底部压入一个新值。返回值是添加新值后的数组长度。

1
2
3
4
5
6
7
var arr = [];
arr.unshift('aya'); //1
arr.unshift('vec', 'love'); //3
console.log(arr); //["vec", "love", "aya"]

slice

复制数组中的一段元素。slice 方法的第一个参数为复制起始位置,第二个参数为复制终止位置。若仅有一个参数,则复制到结尾。

1
2
3
4
5
6
7
8
9
10
var arr = [2, 5, 1, 3, 7];
arr.slice(3); //[3, 7]
arr.slice(3, 3); //[] 因为起始位置和结束位置都相同,所以复制不到数组
arr.slice(3, 4); //[3]
console.log(arr); //[2, 5, 1, 3, 7]; //不会影响原数组

splice

直接在数组上切割元素,切割出来的元素作为返回值。splice 方法的第一个参数是截取起始位置,第二个参数是截取的字符数。

若仅有一个参数,则截取至数组结尾。

1
2
3
4
5
6
7
8
var arr = [2, 5, 1, 3, 7];
arr.splice(2); //[1, 3, 7]
console.log(arr); //[2, 5]
arr = [2, 5, 1, 3, 7];
arr.splice(1, 3); //[5, 1, 3]
console.log(arr); //[2, 7]

splice 的一个用法就是删除数组中的某个元素。

1
2
3
4
5
6
7
8
Array.prototype.remove = function (cursor) {
return this.splice(cursor, 1)[0];
};
arr = [2, 5, 1, 3, 7];
arr.remove(2); //1
console.log(arr); //[2, 5, 3, 7]

sort

数组排序

1
2
3
4
5
[3, 6, 2, 5, 2].sort((itemA, itemB) => {
console.log(itemA, itemB);
return itemA > itemB;
})

ES6

fill

填充数组

find

从数组中查找元素。用函数作为循环体遍历数组中所有元素,若函数返回 类true 类型的值则结束遍历,并且 find 方法将返回当前元素的值。若直到遍历结束都未存在 类true 值,find 方法将会返回 undefined

1
2
3
4
5
6
7
8
9
10
11
12
const peoples = ['vec', 'aya', 'older'];
let name = peoples.find((item, cursor, total) => {
return item === 'aya';
});
if (name !== undefined) {
console.info(`存在 ${name} 这个人`);
} else {
console.warn(`这个人不存在`);
}

findIndex

从数组中查找元素。用函数作为循环体遍历数组中所有元素,若函数返回 类true 类型的值则结束遍历,并且 find 方法将返回当前元素的数组游标。若直到遍历结束都未存在 类true 值,则 find 方法返回 -1

1
2
3
4
5
6
7
8
9
10
11
12
const peoples = ['vec', 'aya', 'older'];
let nameCursor = peoples.findIndex((item, cursor, total) => {
return item === 'aya';
});
if (nameCursor !== -1) {
console.info(`存在 ${peoples[nameCursor]} 这个人`);
} else {
console.warn(`这个人不存在`);
}

includes

检查数组中是否存在某种值。需要注意的是,includes 方法内部采用严格相等来比较数组元素,所以,在数组中检查复合类型数值时,必须非常小心。

1
2
3
4
5
6
7
8
9
var obj = {};
var arr = [ 'vec', 'aya', obj];
arr.includes('aya'); //true
arr.includes('titor'); //false
arr.includes({}); //false
arr.includes(obj); //true

keys

values