map()
map()
方法创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。有点绕口,直接上例子。
const array1 = [1, 4, 9, 16];
// 数组中的每个数都乘以2
const map1 = array1.map(x => x * 2);
console.log(map1);
// 输出结果:数组 [2, 8, 18, 32];
// 如果是计算平方
const map2 = array1.map(x => x * x);
console.log(map2);
// 输出结果:数组 [1, 16, 81, 256];
// 也可以这样计算平方根
const map3 = numbers.map(Math.sqrt);
console.log(map3);
// 输出结果:数组 [1, 2, 3, 4];
reduce()
reduce()
方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。这个更难理解。。。还是直接上例子吧。
const array1 = [1, 2, 3, 4];
const reducer = (previousValue, currentValue) => previousValue + currentValue;
// 1 + 2 + 3 + 4
console.log(array1.reduce(reducer));
// 输出: 10
// 5 + 1 + 2 + 3 + 4
console.log(array1.reduce(reducer, 5));
// 输出: 15
reducer 函数接收4个参数:
- Accumulator (acc) (累计器)
- Current Value (cur) (当前值)
- Current Index (idx) (当前索引)
- Source Array (src) (源数组)
您的 reducer 函数的返回值分配给累计器,该返回值在数组的每个迭代中被记住,并最后成为最终的单个结果值。
reduce() 如何运行
假如运行下段reduce()
代码:
[0, 1, 2, 3, 4].reduce(function(accumulator, currentValue, currentIndex, array){
return accumulator + currentValue;
});
callback 被调用四次,每次调用的参数和返回值如下表:
callback | accumulator(累计数) | currentValue(当前值) | currentIndex(下标) | array(数组) | 返回值 |
---|---|---|---|---|---|
第一次调用 | 0 | 1 | 1 | [0, 1, 2, 3, 4] | 1 |
第二次调用 | 1 | 2 | 2 | [0, 1, 2, 3, 4] | 3 |
第三次调用 | 3 | 3 | 3 | [0, 1, 2, 3, 4] | 6 |
第四次调用 | 6 | 4 | 4 | [0, 1, 2, 3, 4] | 10 |
由reduce
返回的值将是最后一次回调返回值(10)。
你还可以使用箭头函数来代替完整的函数。 下面的代码将产生与上面的代码相同的输出:
[0, 1, 2, 3, 4].reduce((prev, curr) => prev + curr );
如果你打算提供一个初始值作为reduce()
方法的第二个参数,以下是运行过程及结果:
[0, 1, 2, 3, 4].reduce((accumulator, currentValue, currentIndex, array) => {
return accumulator + currentValue
}, 10)
callback | accumulator(累计数) | currentValue(当前值) | currentIndex(下标) | array(数组) | 返回值 |
---|---|---|---|---|---|
第一次调用 | 10 | 0 | 0 | [0, 1, 2, 3, 4] | 10 |
第二次调用 | 10 | 1 | 1 | [0, 1, 2, 3, 4] | 11 |
第三次调用 | 11 | 2 | 2 | [0, 1, 2, 3, 4] | 13 |
第四次调用 | 13 | 3 | 3 | [0, 1, 2, 3, 4] | 16 |
第五次调用 | 16 | 4 | 4 | [0, 1, 2, 3, 4] | 20 |
这种情况下reduce()
返回的值是20
。
reduce例子
数组里所有值的和
var sum = [0, 1, 2, 3].reduce(function (accumulator, currentValue) {
return accumulator + currentValue;
}, 0);
// 和为 6
你也可以写成箭头函数的形式:
var total = [ 0, 1, 2, 3 ].reduce(
( acc, cur ) => acc + cur,
0
);
累加对象数组里的值
要累加对象数组中包含的值,必须提供初始值,以便各个item正确通过你的函数。
var initialValue = 0;
var sum = [{x: 1}, {x:2}, {x:3}].reduce(function (accumulator, currentValue) {
return accumulator + currentValue.x;
},initialValue)
console.log(sum) // logs 6
你也可以写成箭头函数的形式:
var initialValue = 0;
var sum = [{x: 1}, {x:2}, {x:3}].reduce(
(accumulator, currentValue) => accumulator + currentValue.x
,initialValue
);
console.log(sum) // logs 6
将二维数组转化为一维
var flattened = [[0, 1], [2, 3], [4, 5]].reduce(
function(a, b) {
return a.concat(b);
},
[]
);
// flattened is [0, 1, 2, 3, 4, 5]
你也可以写成箭头函数的形式:
var flattened = [[0, 1], [2, 3], [4, 5]].reduce(
( acc, cur ) => acc.concat(cur),
[]
);
计算数组中每个元素出现的次数
var names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
var countedNames = names.reduce(function (allNames, name) {
if (name in allNames) {
allNames[name]++;
}
else {
allNames[name] = 1;
}
return allNames;
}, {});
// countedNames is:
// { 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }
按属性对object分类
var people = [
{ name: 'Alice', age: 21 },
{ name: 'Max', age: 20 },
{ name: 'Jane', age: 20 }
];
function groupBy(objectArray, property) {
return objectArray.reduce(function (acc, obj) {
var key = obj[property];
if (!acc[key]) {
acc[key] = [];
}
acc[key].push(obj);
return acc;
}, {});
}
var groupedPeople = groupBy(people, 'age');
// groupedPeople is:
// {
// 20: [
// { name: 'Max', age: 20 },
// { name: 'Jane', age: 20 }
// ],
// 21: [{ name: 'Alice', age: 21 }]
// }
使用扩展运算符和initialValue绑定包含在对象数组中的数组
// friends - 对象数组
// where object field "books" - list of favorite books
var friends = [{
name: 'Anna',
books: ['Bible', 'Harry Potter'],
age: 21
}, {
name: 'Bob',
books: ['War and peace', 'Romeo and Juliet'],
age: 26
}, {
name: 'Alice',
books: ['The Lord of the Rings', 'The Shining'],
age: 18
}];
// allbooks - list which will contain all friends' books +
// additional list contained in initialValue
var allbooks = friends.reduce(function(prev, curr) {
return [...prev, ...curr.books];
}, ['Alphabet']);
// allbooks = [
// 'Alphabet', 'Bible', 'Harry Potter', 'War and peace',
// 'Romeo and Juliet', 'The Lord of the Rings',
// 'The Shining'
// ]
数组去重
注意: 如果你正在使用一个可以兼容Set 和 Array.from() 的环境, 你可以使用let orderedArray = Array.from(new Set(myArray));
来获得一个相同元素被移除的数组。
let myArray = ['a', 'b', 'a', 'b', 'c', 'e', 'e', 'c', 'd', 'd', 'd', 'd']
let myOrderedArray = myArray.reduce(function (accumulator, currentValue) {
if (accumulator.indexOf(currentValue) === -1) {
accumulator.push(currentValue)
}
return accumulator
}, [])
console.log(myOrderedArray) // ['a', 'b', 'c', 'e', 'd']
let arr = [1,2,1,2,3,5,4,5,3,4,4,4,4];
let result = arr.sort().reduce((init, current) => {
if(init.length === 0 || init[init.length-1] !== current) {
init.push(current);
}
return init;
}, []);
console.log(result); //[1,2,3,4,5]
相关链接:
MDN reduce