# Array.reduce() 左至右歸約 `array.reduce(callback(accumulator, currentValue, currentIndex, array), initialValue)` 將陣列中的每一個元素依序傳入一個[回調函式](/_euUA6bnRwOjECFZalEn3w),將數組中的每個元素組合成一個單一的值。 __accumulator__ 累加器,保存了上一次回調函式返回的值,或是初始值(如果提供了初始值)。 __currentValue__ 當前處理的陣列元素的值。 __currentIndex__(可選) 當前處理的陣列元素的索引。 __array__(可選) 原始陣列。 __initialValue__(可選) 初始值,如果提供了初始值,它將作為第一次調用回調函式時的 accumulator 的初始值。如果未提供初始值,則將使用陣列的最後一個元素作為初始值,並從倒數第二個元素開始遍歷。 ## 使用方法 計算訂單中所有商品的總金額 ``` const order = [ { product: '手机', price: 599 }, { product: '平板电脑', price: 299 }, { product: '耳机', price: 49 }, { product: '充电器', price: 19 }, ]; const totalPrice = order.reduce((accumulator, currentItem) => { return accumulator + currentItem.price; }, 0); console.log('订单总额:', totalPrice); //订单总额: 966 ``` ## 簡化原理 ### Leetcode 2626 Array Reduce Transformation ``` const reduce = (nums, fn, init) => { if (nums.length == 0) {return init;}; let val = init; for (let i = 0; i < nums.length; i++) { val = fn(val, nums[i]); } return val; } ``` Testcase ``` let nums = [1,2,3,4]; function sum(accum, curr) { return accum + curr; } let init = 0; console.log(reduce(nums,sum,init)); ``` 使用 Array.reduce() ``` let nums = [1,2,3,4]; let val = nums.reduce((accum, curr)=>(accum+curr),0); console.log(val); ``` ## 相關練習 ### LeetCode 2695 Array Wrapper 創建一個類“ArrayWrapper”,在其構造函數中接受整數數組。 這個類應該有兩個特點: Create a class `ArrayWrapper` that accepts an array of integers in its constructor. This class should have two features: - 當使用“+”運算符將此類的兩個實例相加時,結果值是兩個數組中所有元素的總和。 When two instances of this class are added together with the `+` operator, the resulting value is the sum of all the elements in both arrays. - 當在實例上調用“String()”函數時,它將返回一個用括號括起來的逗號分隔字符串。 例如,“[1,2,3]”。 When the `String()` function is called on the instance, it will return a comma separated string surrounded by brackets. For example, `[1,2,3]`. #### 解決方案 - valueOf() - 使用Array.flat(1); 將多維陣列平坦化為一維陣列 - 使用Array.reduce(); 相加所有元素 - toString() - 使用Array.join(,) 把所有的元素中間用,隔開並組合成字串 ```javascript class ArrayWrapper { //this.nums=[[1,2],[3,4]] constructor(nums) { this.nums = nums; } valueOf() { const flattenArray = this.nums.flat(1); return flattenArray.reduce((sum, num) => sum + num, 0); } toString() { return `[${this.nums.join(',')}]`; } } ```