共计 2913 个字符,预计需要花费 8 分钟才能阅读完成。
前言
在实际 js 开发中对数组操作频率非常高,看过一些小伙伴的一些用法,挺有意思,在这里小记(不全)一下,备忘。
5 个迭代方法:every、filter、forEach、map 和 some
every():对数组中的每一项运行给定函数,如果该函数每一项都返回 true,则返回 true;
filter():对数组中的每一项运行给定函数,返回该函数会返回 true 的项组成的数组;
forEach():对数组中的每一项运行给定函数,这个方法没有返回值;
map():对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组;
some():对数组中的每一项运行给定函数,如果该函数任意一项返回 true,则返回 true;
// every
var numbers = [1, 2, 3, 4, 5, 6, 7];
var everyResult = numbers.every(function (item, index, array) {
return (item > 2);
});
console.log(everyResult); // false
// some
someResult = numbers.some(function (item, index, array) {
return (item > 2);
});
console.log(someResult); // true
// filter
var filterResult = numbers.filter(function (item, index, array) {
return (item > 2);
});
console.log(filterResult); // [3, 4, 5, 6, 7]
// map
var mapResult = numbers.map(function (item, index, array) {
return item * 2;
});
console.log(mapResult); // [2, 4, 6, 8, 10, 12, 14]
一个归并方法:reduce
array.reduce(callback[, initialValue]) 第一个参数是每一项上调用的函数,该函数有四个参数:
accumulator:累加回调返回值;他是上一次调用时返回的累积值,或 initValue;
currentValue:数组中正在处理的元素;
currentIndex:数组中正在处理的当前元素的索引。如果提供了 initialValue,这索引号为 0,否则索引为 1;
array:调用 reduce() 的数组。
当第二个参数省略时,遍历从数组第二项开始,数组第一项被当作前一个值 accumulator。
数组求和
const numbers = [10, 20, 30, 40];
numbers.reduce((acc, cur, index, arr) => {
console.log(‘acc: ‘ + acc + ‘; ‘ + ‘cur: ‘ + cur + ‘;’);
return acc + cur;
})
结果为:
acc: 10; cur: 20;
acc: 30; cur: 30;
acc: 60; cur: 40;
这第二个参数就是设置 accumulator 的初始类型和初始值,比如为 0,就表示 accumulator 的初始值为 Number 类型,值为 0,因此,reduce 的最终结果也会是 Number 类型。
const numbers = [10, 20, 30, 40];
numbers.reduce((acc, cur, index, arr) => {
console.log(‘acc: ‘ + acc + ‘; ‘ + ‘cur: ‘ + cur + ‘;’);
return acc + cur;
}, 0)
结果为:
acc: 0; cur: 10;
acc: 10; cur: 20;
acc: 30; cur: 30;
acc: 60; cur: 40;
强大的 reduce
reduce 作为归并方法,在有些情形可以替代其它数组操作方法,强大之处,还得要落实在具体的案例上。
假设现在有一个数列 [10, 20, 30, 40, 50],每一项乘以 2,然后筛选出大于 60 的项。
在这里更新数组每一项(map 的功能)然后筛选出一部分(filter 的功能),如果是先使用 map 然后 filter 的话,你需要遍历这个数组两次。在这里用 reduce 更高效。
var numbers = [10, 20, 30, 40, 50];
var result = numbers.reduce(function (acc, cur) {
cur = cur * 2;
if (cur > 60) {
acc.push(cur);
}
return acc;
}, []);
console.log(result); // [80, 100]
从这个例子可以看出 reduce 完成了 map 和 filter 的使命。
统计数组中重复出现项的个数,用对象表示。
var letters = [‘A’, ‘B’, ‘C’, ‘C’, ‘B’, ‘C’, ‘C’];
var letterObj = letters.reduce(function (acc, cur) {
acc[cur] = acc[cur] ? ++acc[cur] : 1;
return acc;
}, {});
console.log(letterObj); // {A: 1, B: 2, C: 4}
数组去重
var letters = [‘A’, ‘B’, ‘C’, ‘C’, ‘B’, ‘C’, ‘C’];
var letterArr = letters.reduce(function (acc, cur) {
if (acc.indexOf(cur) === -1) {
acc.push(cur);
}
return acc;
}, []);
console.log(letterArr); // [“A”, “B”, “C”]
ps:了解更多数组去重方法,点这里。
与 ES6 的结合
与 ES6 结合使用也会擦出不少火花。
删除目标对象某个属性。
const person = {
name: ‘jazz’,
gender: ‘male’,
age: 24
};
const personUnknowAge = Object.keys(person).filter((key) => {
return key !== ‘age’;
})
.map((key) => {
return {
[key]: person[key]
}
})
.reduce((acc, cur) => {
return {…acc, …cur};
}, {});
console.log(personUnknowAge); // {name: “jazz”, gender: “male”}
更简洁的方案,利用 ES6 中函数参数解构:
const personUnknowAge = (({name, gender}) => ({name, gender}))(person);
console.log(personUnknowAge); // {name: “jazz”, gender: “male”}
当然还有更简单的方案,利用 ES6 中对象解构:
const person = {
name: ‘jazz’,
gender: ‘male’,
age: 24
};
let {age, …personUnknowAge} = person;
console.log(personUnknowAge); // {name: “jazz”, gender: “male”}
结尾
数组操作的“妙用”远不止这些,后面有空再研究补充吧,完~