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 的行为,能够处理传入初始值和不传入初始值的情况,并在处理空数组时做了相应的错误处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/633900.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Orcle查询组合字段重复的数据

oracle拼接字符串 在Oracle中&#xff0c;可以使用||运算符或CONCAT函数来拼接字符串。 使用||运算符&#xff1a; SELECT Hello, || World! AS concatenated_string FROM dual;使用CONCAT函数&#xff1a; SELECT CONCAT(Hello, , World!) AS concatenated_string FROM d…

智慧医疗时代:探索互联网医院开发的新篇章

在智慧医疗时代&#xff0c;互联网医院开发正引领着医疗服务的创新浪潮。通过将先进的技术与医疗服务相结合&#xff0c;互联网医院为患者和医生提供了全新的互动方式&#xff0c;极大地提升了医疗服务的便捷性和效率。本文将深入探讨互联网医院的开发&#xff0c;介绍其技术实…

如何彻底搞懂迭代器(Iterator)设计模式?

说起迭代器&#xff08;Iterator&#xff09;&#xff0c;相信你并不会陌生&#xff0c;因为我们几乎每天都在使用JDK中自带的各种迭代器。那么&#xff0c;这些迭代器是如何构建出来的呢&#xff1f;就需要用到了今天内容要介绍的迭代器设计模式。在日常开发过程中&#xff0c…

多尺度注意力机制突破性成果!低成本、高性能兼备

与传统的注意力机制相比&#xff0c;多尺度注意力机制引入了多个尺度的注意力权重&#xff0c;让模型能够更好地理解和处理复杂数据。 这种机制通过在不同尺度上捕捉输入数据的特征&#xff0c;让模型同时关注局部细节和全局结构&#xff0c;以提高对细节和上下文信息的理解&a…

开源大模型与闭源大模型:技术哲学的较量

目录 前言一、 开源大模型的优势1. 社区支持与合作1.1 全球协作网络1.2 快速迭代与创新1.3 共享最佳实践 2. 透明性与可信赖性2.1 审计与验证2.2 减少偏见与错误2.3 安全性提升 3. 低成本与易访问性3.1 降低研发成本3.2 易于定制化3.3 教育资源丰富 4. 促进标准化5. 推动技术进…

3d选择模型后不能旋转什么原因?怎么解决?---模大狮模型网

在3D建模和渲染的过程中&#xff0c;旋转模型是常见的操作。然而&#xff0c;有时在选择了模型后&#xff0c;却发现无法进行旋转&#xff0c;这可能会让许多用户感到困扰。本文将探讨3D选择模型后不能旋转的可能原因&#xff0c;并提供相应的解决方法。 一、3D选择模型后不能旋…

Zynq-Linux移植学习笔记之68- 国产ZYNQ添加用户自定义版本信息

1、背景介绍 在使用复旦微zynq时&#xff0c;有时候虽然针对uboot源码进行了改动&#xff0c;但由于uboot基线版本只有一个&#xff08;2018-07-fmsh&#xff09;&#xff0c;导致无法区分版本信息&#xff0c;虽然可以通过编译时间来区分&#xff0c;但没有版本号直观。内核也…

快速搭建 WordPress 外贸电商网站指南

本指南全面解析了在 Hostinger 平台上部署 WordPress 外贸电商网站的详细步骤&#xff0c;涵盖托管方案选择、WordPress 一键安装、主题挑选与演示数据导入、主题个性化定制、SEO插件插件 AIOSEO 安装、通过 GTranslate 实现多语言自动翻译、地区访问控制插件&#xff0c;助力用…

高中数学:平面向量-数量积(向量与向量的乘积)与投影

一、引题 物理上的力做功 二、数量积与投影 1、数量积 θ的范围是[0,π] 2、投影 向量的投影&#xff0c;依然是一个向量&#xff01; 3、运算法则 易错点&#xff1a; 4、重要性质 这里对性质(2)要注意一下&#xff1a;如果 a → \mathop{a}\limits ^{\rightarrow…

30.包名的修改和新建后端模块

权限和第三方登录确实令人头疼,我们来学一点简单一点的。 另外,如果各位有属于自己的域名和ICP/IP备案,布置一个作业,自行实现第三方QQ登录。 我们所说的包名修改,是一次性修改ruoyi的全部包名,因为发现很多人有这样的需求,下载别人的代码,想要改成自己公司的包名,结…

当代家庭教育杂志社《当代家庭教育》杂志社24年第6期目录

家庭教育资讯 《家庭教育蓝皮书2024:中国家庭养育环境报告》出炉 4 2024年4月至7月北京市将开展“双减”专项行动 5 小学生玩“烟卡”到底该不该禁&#xff1f; 5 家庭教育理论探索 新时代家长家庭教育素养&#xff1a;意涵、关键要素及其培育 周起煌; 6-10 …

海外仓WMS系统多少钱?家庭海外仓怎么选合适的系统

作为海外仓管理的核心工具&#xff0c;WMS系统能够帮助企业实现仓库的可视化管理&#xff0c;流程自动化以及决策的数据化支持&#xff0c;进而提升海外仓的整体竞争力。 然而&#xff0c;许多海外仓企业在选择wms系统的时候&#xff0c;往往对价格的疑虑比较大&#xff0c;不…

微服务远程调用 RestTemplate

Spring给我们提供了一个RestTemplate的API&#xff0c;可以方便的实现Http请求的发送。 同步客户端执行HTTP请求&#xff0c;在底层HTTP客户端库(如JDK HttpURLConnection、Apache HttpComponents等)上公开一个简单的模板方法API。RestTemplate通过HTTP方法为常见场景提供了模…

Xinstall全渠道统计服务,洞悉App推广效果

在当今数字化时代&#xff0c;App已经成为企业和个人进行业务推广和服务提供的重要渠道。然而&#xff0c;随着App市场的日益饱和&#xff0c;如何有效地推广和运营App成为了众多广告主和开发者面临的难题。而App渠道统计作为衡量推广效果、优化运营策略的重要手段&#xff0c;…

大数据运维学习笔记之Ambari——筑梦之路

原则&#xff1a;分布式存储和分布式计算分开 今天就到这里啦。

Github上传时报错The file path is empty的解决办法

问题截图 文件夹明明不是空的&#xff0c;却怎么都上传不上去。 解决方案&#xff1a; 打开隐藏文件的开关&#xff0c;删除原作者的.git文件 如图所示&#xff1a; 上传成功&#xff01;

JS片段:如何将文本复制到剪贴板

在构建网站时&#xff0c;一个非常普遍的需求是能够通过单击按钮将文本复制到剪贴板。在现代浏览器中&#xff0c;使用navigator.clipboardAPI 访问系统剪切板&#xff0c;利用clipboard.writeText复制到剪贴板&#xff0c;再通过clipboard.readText获取剪贴板内容即可实现。 …

APH-Archives of Public Health

文章目录 一、期刊简介二、征稿信息三、期刊表现四、投稿须知五、投稿咨询 一、期刊简介 Archives of Public Health是一份范围广泛的公共卫生杂志&#xff0c;致力于出版公共卫生领域所有可靠的科学。该杂志旨在更好地了解人群的健康。该杂志有助于公共卫生知识&#xff0c;加…

Debug-010-git stash的用法及使用场景

问题原因&#xff1a; 其实也不是最近&#xff0c;就是之前就碰到过这个问题&#xff0c;那就是我正在新分支开发新功能&#xff0c;开发程度还没有到可以commit的程度&#xff0c;我不想提交(因为有些功能没有完全实现&#xff0c;而且没有自测的话很容易有问题&#xff0c;提…

智能车竞赛指南:从零到一,驶向自动驾驶的未来

智能车竞赛指南&#xff1a;从零到一&#xff0c;驶向自动驾驶的未来 一、智能车竞赛概览1.1 竞赛介绍1.2 竞赛分类 二、智能车开发技术基础2.1 硬件平台2.2 软件开发 三、实战案例&#xff1a;循线小车开发3.1 系统架构3.2 代码示例 四、技术项目&#xff1a;基于ROS的视觉导航…