数组的reduce是可以指定返回的值
reduce使用场景
数组和对象中的值相加
let total = [ 0, 1, 2, 3 ].reduce(
( previousValue, currentValue ) => previousValue + currentValue,
0
)
let initialValue = 0
let sum = [{x: 1}, {x: 2}, {x: 3}].reduce(
(previousValue, currentValue) => previousValue + currentValue.x
, initialValue
)
console.log(sum)
二维数组转换为一维数组
let flattened = [[0, 1], [2, 3], [4, 5]].reduce(
( previousValue, currentValue ) => previousValue.concat(currentValue),
[]
)
计算数组中每个元素出现的次数
let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice']
let 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 }
按照属性对obj进行分类
let people = [ { name: 'Alice', age: 21 }, { name: 'Max', age: 20 }, { name: 'Jane', age: 20 }];
function groupBy(objectArray, property) {
return objectArray.reduce(function (acc, obj) {
let key = obj[property]
if (!acc[key]) {
acc[key] = []
}
acc[key].push(obj)
return acc
}, {})
}
let groupedPeople = groupBy(people, 'age')
利用扩展运算符和reduce扩展对象中的数组
// friends - an array of objects
// where object field "books" is a list of favorite books
let 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
}]
let allbooks = friends.reduce(function(previousValue, currentValue) {
return [...previousValue, ...currentValue.books]
}, ['Alphabet'])
allbooks = [ 'Alphabet', 'Bible', 'Harry Potter', 'War and peace', 'Romeo and Juliet', 'The Lord of the Rings', 'The Shining' ]
实现管道函数
const double = x => x + x
const triple = x => 3 * x
const quadruple = x => 4 * x
const pipe = (...functions) => initialValue => functions.reduce(
(acc, fn) => fn(acc),
initialValue
)
const multiply6 = pipe(double, triple)
const multiply9 = pipe(triple, triple)
const multiply16 = pipe(quadruple, quadruple)
const multiply24 = pipe(double, triple, quadruple)
multiply6(6)
multiply9(9)
multiply16(16)
multiply24(10)
实现map
if (!Array.prototype.mapUsingReduce) {
Array.prototype.mapUsingReduce = function(callback, initialValue) {
return this.reduce(function(mappedArray, currentValue, currentIndex, array) {
mappedArray[currentIndex] = callback.call(initialValue, currentValue, currentIndex, array)
return mappedArray
}, [])
}
}
[1, 2, , 3].mapUsingReduce(
(currentValue, currentIndex, array) => currentValue + currentIndex + array.length
)
按顺序执行Promise
function runPromiseInSequence(arr, input) {
return arr.reduce(
(promiseChain, currentFunction) => promiseChain.then(currentFunction),
Promise.resolve(input)
)
}
function p1(a) {
return new Promise((resolve, reject) => {
resolve(a * 5)
})
}
function p2(a) {
return new Promise((resolve, reject) => {
resolve(a * 2)
})
}
function f3(a) {
return a * 3
}
function p4(a) {
return new Promise((resolve, reject) => {
resolve(a * 4)
})
}
const promiseArr = [p1, p2, f3, p4]
runPromiseInSequence(promiseArr, 10)
.then(console.log)