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;// 判断是否传入 initialValueif (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); // 输出:15const 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.mzph.cn/news/839047.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微服务:利用RestTemplate实现远程调用

打算系统学习一下微服务知识&#xff0c;从今天开始记录。 远程调用 调用order接口&#xff0c;查询。 由于实现还未封装用户信息&#xff0c;所以为null。 下面我们来使用远程调用用户服务的接口&#xff0c;然后封装一下用户信息返回即可。 流程图 配置类中注入RestTe…

文心一言 VS 讯飞星火 VS chatgpt (265)-- 算法导论20.1 4题

四、假设不使用一棵叠加的度为 u \sqrt{u} u ​ 的树&#xff0c;而是使用一棵叠加的度为 u 1 k u^{\frac{1}{k}} uk1​的树&#xff0c;这里 k 是大于 1 的常数&#xff0c;则这样的一棵树的高度是多少&#xff1f;又每个操作将需要多长时间&#xff1f;如果要写代码&#xf…

模板中的右值引用(万能引用)、引用折叠与完美转发

模板中的右值引用&#xff08;万能引用&#xff09;、引用折叠与完美转发 文章目录 模板中的右值引用&#xff08;万能引用&#xff09;、引用折叠与完美转发一、万能引用与引用折叠1. 模板中的右值引用2. 自动类型推导(auto)与万能引用3. 引用折叠与万能引用4. lambda表达式捕…

数据可视化第十天(爬虫爬取某瓣星际穿越电影评论,并且用词云图找出关键词)

开头提醒 本次爬取的是用户评论&#xff0c;只供学习使用&#xff0c;不会进行数据的传播。希望大家合法利用爬虫。 获得数据 #总程序 import requests from fake_useragent import UserAgent import timefuUserAgent()headers{User-Agent:fu.random }page_listrange(0,10) …

音视频入门基础:像素格式专题(3)——FFmpeg源码解析BMP格式图片的底层实现原理

音视频入门基础&#xff1a;像素格式专题系列文章&#xff1a; 音视频入门基础&#xff1a;像素格式专题&#xff08;1&#xff09;——RGB简介 音视频入门基础&#xff1a;像素格式专题&#xff08;2&#xff09;——不通过第三方库将RGB24格式视频转换为BMP格式图片 音视频…

创建一个vue3项目

## 1.创建命令 npm create vuelatest ## 2.具体配置 ## 配置项目名称 √ Project name: vue3_test ## 是否添加TypeScript支持 √ Add TypeScript? Yes ## 是否添加JSX支持 √ Add JSX Support? No ## 是否添加路由环境 √ Add Vue Router for Single Page Application de…

人工智能+量子计算:飞跃现实边界还是科技幻想?

人工智能量子计算&#xff0c;这是一种可能改变世界的伙伴关系。 在科技的前沿&#xff0c;两大革命性技术——人工智能&#xff08;AI&#xff09;和量子计算——正站在合作的十字路口。人工智能&#xff0c;以其强大的数据分析能力和模式识别&#xff0c;正在改变着我们生活…

传感器通过Profinet转Modbus网关与PLC通讯在生产线的应用

Profinet转Modbus&#xff08;XD-MDPN100/300&#xff09;网关可视作一座桥梁&#xff0c;能够实现Profinet协议与Modbus协议相互转换&#xff0c;支持Modbus RTU主站/从站&#xff0c;并且Profinet转Modbus网关设备自带网口和串口&#xff0c;既可以实现协议的转换&#xff0c…

前端基础入门三大核心之HTML篇:探索WebAssembly —— 开启网页高性能应用新时代

前端基础入门三大核心之HTML篇&#xff1a;探索WebAssembly —— 开启网页高性能应用新时代 WebAssembly基础概念工作原理概览WebAssembly实战示例基本使用 安全性与性能优化防范漏洞实践实际工作中的使用技巧结语与讨论 随着Web技术的飞速发展&#xff0c;前端开发者面临越来越…

全文检索ElasticSearch简介

1 全文检索 1.1 什么是全文检索 全文检索是一种通过对文本内容进行全面索引和搜索的技术。它可以快速地在大量文本数据中查找包含特定关键词或短语的文档,并返回相关的搜索结果。全文检索广泛应用于各种信息管理系统和应用中,如搜索引擎、文档管理系统、电子邮件客户端、新闻…

Mac虚拟机工具 CrossOver 24.0.0 Beta3 Mac中文版

CrossOver是一款在Mac上运行Windows应用程序的软件&#xff0c;无需安装虚拟机或重启计算机&#xff0c;简化了操作过程&#xff0c;提高了工作效率&#xff0c;为用户带来便捷体验。前往Mac青桔下载&#xff0c;享受前所未有的便利和高效。摘要由作者通过智能技术生成 CrossOv…

【FAQ】HarmonyOS SDK 闭源开放能力 —IAP Kit(2)

1.问题描述&#xff1a; 应用内支付IAP Kit和Payment Kit的区别以及适用场景&#xff1f; 解决方案&#xff1a; IAP Kit是四方支付&#xff0c;仅支持在线虚拟商品&#xff0c;如会员&#xff0c;游戏钻石等&#xff0c;双框架支持全球&#xff0c;目前单框架暂时只支持国内…

Qml:线程

import QtQuick import QtQuick.Controls Window {width: 640height: 480visible: truetitle: qsTr("Test Thread")//定时器测试//显示时钟Text {id: xtimex:parent.width-220y:parent.height-30text:"time"MouseArea{anchors.fill:parentonClicked:{timer…

【MySQL精通之路】SQL优化(1)-查询优化(8)-嵌套联接优化

主博客&#xff1a; 【MySQL精通之路】SQL优化(1)-查询优化-CSDN博客 上一篇&#xff1a; 【MySQL精通之路】SQL优化(1)-查询优化(7)-嵌套循环联接-CSDN博客 下一篇&#xff1a; 【MySQL精通之路】SQL优化(1)-查询优化(9)-外部联接优化-CSDN博客 与SQL标准相比&#xff0c…

robosuite导入自定义机器人

目录 目的&#xff1a;案例一&#xff1a;成果展示具体步骤&#xff1a;URDF文件准备xml文件生成xml修改机器人构建 目的&#xff1a; 实现其他标准/非标准机器人的构建 案例一&#xff1a; 成果展示 添加机器人JAKA ZU 7 这个模型 具体步骤&#xff1a; URDF文件准备 从…

python-docx 在word中指定位置插入图片或表格

docx库add_picture()方法不支持对图片位置的设置 1、新建一个1行3列的表格&#xff0c;在中间的一列中插入图片 from docx import Document from docx.shared import Pt from docx.oxml.shared import OxmlElement from docx.enum.text import WD_ALIGN_PARAGRAPHdef add_cen…

Nacos 进阶篇---Nacos服务端怎么维护不健康的微服务实例 ?(七)

一、引言 在 Nacos 后台管理服务列表中&#xff0c;我们可以看到微服务列表&#xff0c;其中有一栏叫“健康实例数” &#xff08;如下图&#xff09;&#xff0c;表示对应的客户端实例信息是否可用状态。 那Nacos服务端是怎么感知客户端的状态是否可用呢 &#xff1f; 本章…

Flutter 中的 AnimatedPhysicalModel 小部件:全面指南

Flutter 中的 AnimatedPhysicalModel 小部件&#xff1a;全面指南 Flutter 的 AnimatedPhysicalModel 是一个功能强大的小部件&#xff0c;它允许开发者创建具有物理效果的动画形状变换。这个小部件非常适合需要展示平滑过渡和动态交互的场景&#xff0c;如按钮按下效果、卡片…

Rust:多线程环境下使用 Mutex<T> 还是 Arc<Mutex<T>> ?

在 Rust 中&#xff0c;Mutex 本身不是线程不安全的&#xff1b;它提供了内部的线程同步机制。然而&#xff0c;如果你想在多线程环境中共享同一个 Mutex&#xff0c;你需要确保这个 Mutex 可以被多个线程访问。为此&#xff0c;你通常需要使用 Arc<Mutex<T>>。Arc…