JavaScript 中的数组方法

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

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

ES5

这里是 ES5 适用的数组方法

forEach

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

var arr = ['hello', ', ', 'Wrold!'];

/* item 为数组元素,cursor 为数组游标,total 为数组自身(total === arr) */
arr.forEach((item, cursor, total) => {
    console.log(
        `我是 ${item},` +
        `我在数组里排第 ${cursor + 1} 个,` +
        `这个数组是: ${JSON.stringify(total)}`
    );
});

map

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

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

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

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 类型的值则保留当前数组元素。

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 方法内部采用严格相等来比较数组元素,所以,在使用复合类型数值时,必须非常小心

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 相似,只不过它是由数组顶部开始查找。

var arr = [ 3, 3, 4, 3, 3 ];

console.log(arr.lastIndexOf(3));    //4

join

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

var arr = [ 'C', 'Java', 'Python' ];

arr.join(); //"C,Java,Python"
arr.join('');   //"CJavaPython"

push

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

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

var peoples = [ 'aya', 'vec' ];

console.log(`${peoples.pop()} love ${peoples.pop()}`)
//vec love aya

reduce

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

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的顺序迭代数组。

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

颠倒数组顺序。

var strArr = 'aya evol cev'.split('');

strArr.reverse();

console.log(strArr.join(''));
//vec love aya

shift

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

var arr = ['v', 'e'];

arr.shift();    //"v"
arr.shift();    //"e"
arr.shift();    //undefined

unshift

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

var arr = [];

arr.unshift('aya'); //1
arr.unshift('vec', 'love'); //3

console.log(arr);   //["vec", "love", "aya"]

slice

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

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 方法的第一个参数是截取起始位置,第二个参数是截取的字符数。

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

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 的一个用法就是删除数组中的某个元素。

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

数组排序

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

ES6

fill

填充数组

find

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

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

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 方法内部采用严格相等来比较数组元素,所以,在数组中检查复合类型数值时,必须非常小心。

var obj = {};
var arr = [ 'vec', 'aya', obj];

arr.includes('aya');    //true
arr.includes('titor');  //false
arr.includes({});       //false
arr.includes(obj);      //true

keys

values