JS之Reduce

reduce 是 JavaScript 中 Array 对象的一个方法,用于对数组中的每个元素执行一个提供的函数(称为 reducer 函数),并将其结果汇总为单个返回值。它是一种高阶函数,可以用于数组的累积操作,例如求和、计算乘积、拼接字符串、计算平均值等。

语法

array.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])

参数

  • callback:在数组的每个元素上执行的函数,接受四个参数:
    • accumulator:累积器,累积回调的返回值;它是上一次调用回调时返回的累积值,或初始值(initialValue)。
    • currentValue:数组中正在处理的元素。
    • index(可选):数组中正在处理的当前元素的索引。对于初次调用,索引为0(如果提供了初始值)或1(如果未提供初始值)。
    • array(可选):调用 reduce 的数组。
  • initialValue(可选):作为第一次调用 callback 函数时第一个参数的值。如果没有提供初始值,reduce 会从索引1的元素开始执行 callback 方法,accumulator 是数组中的第一个元素。

返回值

  • 函数最终的累积结果。

示例

1. 数组求和
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
console.log(sum); // 输出:15
2. 数组乘积
const numbers = [1, 2, 3, 4, 5];
const product = numbers.reduce((accumulator, currentValue) => accumulator * currentValue, 1);
console.log(product); // 输出:120
3. 数组扁平化
const nestedArray = [[0, 1], [2, 3], [4, 5]];
const flattenedArray = nestedArray.reduce((accumulator, currentValue) => accumulator.concat(currentValue), []);
console.log(flattenedArray); // 输出:[0, 1, 2, 3, 4, 5]
4. 计算数组中元素出现的次数
const names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
const nameCount = names.reduce((accumulator, currentValue) => {
  accumulator[currentValue] = (accumulator[currentValue] || 0) + 1;
  return accumulator;
}, {});
console.log(nameCount); // 输出:{ Alice: 2, Bob: 1, Tiff: 1, Bruce: 1 }
5. 按属性对对象数组进行分组
const people = [
  { name: 'Alice', age: 21 },
  { name: 'Bob', age: 21 },
  { name: 'Tiff', age: 24 },
  { name: 'Bruce', age: 21 }
];
const groupedByAge = people.reduce((accumulator, currentValue) => {
  const age = currentValue.age;
  if (!accumulator[age]) {
    accumulator[age] = [];
  }
  accumulator[age].push(currentValue);
  return accumulator;
}, {});
console.log(groupedByAge);
// 输出:{ '21': [{ name: 'Alice', age: 21 }, { name: 'Bob', age: 21 }, { name: 'Bruce', age: 21 }], '24': [{ name: 'Tiff', age: 24 }] }

总结

reduce 方法非常强大,适用于各种需要将数组汇总为单个值的操作。通过提供一个初始值,reduce 可以灵活地处理数组的不同类型的数据和复杂的逻辑。掌握 reduce 方法有助于编写简洁、高效的 JavaScript 代码。

要手写一个 reduce 函数,可以按照 Array.prototype.reduce 的规范来实现。我们的 reduce 函数将接受两个参数:一个回调函数和一个可选的初始值。回调函数会在数组的每一个元素上执行,并传入累积器、当前值、当前索引和数组本身。最后,我们的 reduce 函数会返回累积的结果。

以下是手写 reduce 的代码实现:

// 手写 reduce 函数
function myReduce(array, callback, initialValue) {
  // 验证输入
  if (!Array.isArray(array)) {
    throw new TypeError('First argument must be an array');
  }
  if (typeof callback !== 'function') {
    throw new TypeError('Second argument must be a function');
  }

  // 初始化变量
  let accumulator;
  let startIndex;

  // 判断是否传入 initialValue
  if (initialValue !== undefined) {
    accumulator = initialValue;
    startIndex = 0;
  } else {
    if (array.length === 0) {
      throw new TypeError('Reduce of empty array with no initial value');
    }
    accumulator = array[0];
    startIndex = 1;
  }

  // 遍历数组
  for (let i = startIndex; i < array.length; i++) {
    accumulator = callback(accumulator, array[i], i, array);
  }

  return accumulator;
}

// 测试我们的 myReduce 函数
const numbers = [1, 2, 3, 4, 5];
const sum = myReduce(numbers, (accumulator, currentValue) => accumulator + currentValue, 0);
console.log(sum); // 输出:15

const product = myReduce(numbers, (accumulator, currentValue) => accumulator * currentValue, 1);
console.log(product); // 输出:120

// 不传初始值
const sumWithoutInitial = myReduce(numbers, (accumulator, currentValue) => accumulator + currentValue);
console.log(sumWithoutInitial); // 输出:15

代码解释

  1. 输入验证

    • 检查第一个参数是否为数组,如果不是,抛出类型错误。
    • 检查第二个参数是否为函数,如果不是,抛出类型错误。
  2. 初始化变量

    • 如果传入了初始值,将 accumulator 初始化为初始值,startIndex 初始化为 0
    • 如果没有传入初始值,确保数组不为空,然后将 accumulator 初始化为数组的第一个元素,startIndex 初始化为 1
  3. 遍历数组

    • startIndex 开始遍历数组的每一个元素,调用回调函数并更新 accumulator
  4. 返回结果

    • 遍历结束后,返回累积的结果 accumulator

这个手写的 reduce 函数模仿了 Array.prototype.reduce 的行为,能够处理传入初始值和不传入初始值的情况,并在处理空数组时做了相应的错误处理。

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

代码有点萌

谢谢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值