JavaScript 的 reduce() 方法詳解

JavaScript 的 reduce() 方法詳解

reduce() 是 JavaScript 數(shù)組方法中功能最強(qiáng)大的方法之一,它可以將數(shù)組元素通過指定的函數(shù)累積為單個(gè)值。

基本語(yǔ)法

array.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
  • callback:執(zhí)行數(shù)組中每個(gè)元素的函數(shù),包含以下參數(shù):
    • accumulator:累積器,累積回調(diào)的返回值
    • currentValue:數(shù)組中正在處理的當(dāng)前元素
    • index(可選):當(dāng)前元素的索引
    • array(可選):調(diào)用 reduce 的數(shù)組
  • initialValue(可選):作為第一次調(diào)用 callback 時(shí)的第一個(gè)參數(shù)的值

基本用法示例

1. 數(shù)組求和

const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((acc, curr) => acc + curr, 0);
console.log(sum); // 15

2. 數(shù)組求積

const product = numbers.reduce((acc, curr) => acc * curr, 1);
console.log(product); // 120

高級(jí)用法

3. 扁平化二維數(shù)組

const flattened = [[0, 1], [2, 3], [4, 5]].reduce(
  (acc, curr) => acc.concat(curr),
  []
);
console.log(flattened); // [0, 1, 2, 3, 4, 5]

4. 計(jì)算元素出現(xiàn)次數(shù)

const fruits = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple'];
const count = fruits.reduce((acc, fruit) => {
  acc[fruit] = (acc[fruit] || 0) + 1;
  return acc;
}, {});
console.log(count); // { apple: 3, banana: 2, orange: 1 }

5. 按屬性對(duì)對(duì)象數(shù)組分組

const people = [
  { name: 'Alice', age: 21 },
  { name: 'Bob', age: 20 },
  { name: 'Charlie', age: 21 }
];

const groupedByAge = people.reduce((acc, person) => {
  const age = person.age;
  if (!acc[age]) {
    acc[age] = [];
  }
  acc[age].push(person);
  return acc;
}, {});

console.log(groupedByAge);
// {
//   20: [{ name: 'Bob', age: 20 }],
//   21: [
//     { name: 'Alice', age: 21 },
//     { name: 'Charlie', age: 21 }
//   ]
// }

6. 數(shù)組去重

const numbersWithDuplicates = [1, 2, 2, 3, 4, 4, 5];
const uniqueNumbers = numbersWithDuplicates.reduce((acc, curr) => {
  if (!acc.includes(curr)) {
    acc.push(curr);
  }
  return acc;
}, []);
console.log(uniqueNumbers); // [1, 2, 3, 4, 5]

注意事項(xiàng)

  1. 初始值的重要性

    • 如果沒有提供 initialValue,reduce 會(huì)從索引 1 開始執(zhí)行 callback 方法,跳過第一個(gè)索引
    • 如果數(shù)組為空且沒有提供 initialValue,會(huì)拋出 TypeError
    [].reduce((acc, curr) => acc + curr); // TypeError
    
  2. 空數(shù)組處理

    [].reduce((acc, curr) => acc + curr, 0); // 0 (安全)
    
  3. reduceRight

    • 類似 reduce,但是從數(shù)組的末尾向前執(zhí)行
    const flattenedRight = [[0, 1], [2, 3], [4, 5]].reduceRight(
      (acc, curr) => acc.concat(curr),
      []
    );
    console.log(flattenedRight); // [4, 5, 2, 3, 0, 1]
    

實(shí)際應(yīng)用場(chǎng)景

7. 函數(shù)組合

const compose = (...fns) => x => fns.reduceRight((acc, fn) => fn(acc), x);

const add5 = x => x + 5;
const multiply2 = x => x * 2;
const subtract3 = x => x - 3;

const transform = compose(add5, multiply2, subtract3);
console.log(transform(10)); // ((10 - 3) * 2) + 5 = 19

8. 管道操作

const pipe = (...fns) => x => fns.reduce((acc, fn) => fn(acc), x);

const transformPipe = pipe(subtract3, multiply2, add5);
console.log(transformPipe(10)); // ((10 - 3) * 2) + 5 = 19

9. 對(duì)象屬性轉(zhuǎn)換

const obj = {
  user_name: 'john_doe',
  user_age: 30,
  product_id: 123
};

const camelCaseKeys = Object.entries(obj).reduce((acc, [key, value]) => {
  const camelKey = key.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
  acc[camelKey] = value;
  return acc;
}, {});

console.log(camelCaseKeys);
// { userName: 'john_doe', userAge: 30, productId: 123 }

reduce() 方法非常靈活,幾乎可以實(shí)現(xiàn)任何基于數(shù)組的復(fù)雜轉(zhuǎn)換邏輯。掌握好 reduce 可以大大提升你的 JavaScript 編程能力。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容