Array.prototype.reduce()數組
reduce() 方法對數組中的每一個元素執行一個reducer函數(升序執行),將其結果彙總爲單個返回值。app
const arr1 = [1, 2, 3, 4]; const reducer = (accumulator, currentValue) => accumulator + currentValue; // 1 + 2 + 3 + 4 console.log(arr1.reduce(reducer)); // output: 10 // 5 + 1 + 2 + 3 + 4 console.log(arr1.reduce(reducer, 5)); // output: 15
arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
1.參數
callback
執行數組中每一個值(若是沒有提供 initialValue,則第一個值除外)的函數,包含四個參數:函數
accumulator
累計器累計回調的返回值; 它是上一次調用回調時返回的累積值,或initialValue(見於下方)。this
currentValue
數組中正在處理的元素。prototype
index:可選
數組中正在處理的當前元素的索引。 若是提供了 initialValue,則起始索引號爲0,不然從索引1起始。code
array:可選
調用reduce()的數組。對象
initialValue:可選
做爲第一次調用 callback 函數時的第一個參數的值。 若是沒有提供初始值,則將使用數組中的第一個元素。 在沒有初始值的空數組上調用 reduce 將報錯。索引
2.返回值
函數累計處理的結果。ip
回調函數第一次執行時,accumulator 和 currentValue 的取值有兩種狀況:
若是調用reduce()時提供了initialValue,accumulator取值爲initialValue,currentValue取數組中的第一個值;
若是沒有提供 initialValue,那麼accumulator取數組中的第一個值,currentValue取數組中的第二個值。input
注意:若是沒有提供initialValue,reduce 會從索引1的地方開始執行 callback 方法,跳過第一個索引。若是提供initialValue,從索引0開始。
1.求出數組裏全部值的和
let sum = [ 0, 1, 2, 3 ].reduce((acc, cur) => acc + cur, 0); console.log(sum); // 6
2.累加對象數組裏的值
let total = [{x: 1}, {x:2}, {x:3}].reduce((acc, cur) => acc + cur.x, 0); console.log(total); // 6
3.將二維數組轉化爲一維
let flattened = [[0, 1], [2, 3], [4, 5]].reduce((acc, cur) => acc.concat(cur), []); console.log(flattened); // [0, 1, 2, 3, 4, 5]
4.計算數組中每一個元素出現的次數
let names = ['lxcan', 'splendid', 'ican', 'volcano', 'lxcan']; let countedNames = names.reduce((allNames, name) => { if (name in allNames) { allNames[name]++; } else { allNames[name] = 1; } return allNames; }, {}); console.log(countedNames); // { 'lxcan': 2, 'splendid': 1, 'ican': 1, 'volcano': 1 }
5.按屬性對object分類
let peoples = [ { name: 'lxcan', age: 20 }, { name: 'ican', age: 20 }, { name: 'splendid', age: 18 } ]; function groupBy(arr, property) { return arr.reduce((acc, obj) => { let key = obj[property]; if (!acc[key]) { acc[key] = []; } acc[key].push(obj); return acc; }, {}); } let groupedPeople = groupBy(peoples, 'age'); console.log(groupedPeople); // { // 18: [{ name: 'splendid', age: 18 }] // 20: [ // { name: 'lxcan', age: 20 }, // { name: 'ican', age: 20 } // ], // }
6.使用擴展運算符和initialValue綁定包含在對象數組中的數組
// friends - 對象數組 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 Shining'], age: 18 }]; // allbooks - 包含全部朋友的書 + initialValue 中的附加列表 let allBooks = friends.reduce(function(prev, curr) { return [...prev, ...curr.books]; }, ['Alphabet']); console.log(allBooks); // ['Alphabet', 'Bible', 'Harry Potter', 'War and peace', 'Romeo and Juliet', 'The Shining']
7.功能型函數封裝
const double = x => 2 * x; const triple = x => 3 * x; const quadruple = x => 4 * x; // 對功能函數進行封裝 const pipe = (...functions) => { return input => functions.reduce((acc, fn) => fn(acc), input) }; // 用於特定值組合乘法的複合函數 const multiply6 = pipe(double, triple); const multiply9 = pipe(triple, triple); const multiply16 = pipe(quadruple, quadruple); const multiply24 = pipe(double, triple, quadruple); // 使用 multiply6(6); // 36 multiply9(9); // 81 multiply16(16); // 256 multiply24(10); // 240
8.使用 reduce 實現map
if (!Array.prototype.mapByReduce) { Array.prototype.mapByReduce = function(callback, thisArg) { return this.reduce(function(mappedArray, currentValue, index, array) { mappedArray[index] = callback.call(thisArg, currentValue, index, array); return mappedArray; }, []); }; } let arr = [1, 2, 3].mapByReduce((value, index, array) => value + index + array.length); console.log(arr); // [4, 6, 8]