前言
在实际 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"}
来源: https://segmentfault.com/a/1190000017513610