JS之Reduce

ops/2024/10/16 2:25:16/

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

语法

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

参数

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

返回值

  • 函数最终的累积结果。

示例

1. 数组求和
javascript">const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
console.log(sum); // 输出:15
2. 数组乘积
javascript">const numbers = [1, 2, 3, 4, 5];
const product = numbers.reduce((accumulator, currentValue) => accumulator * currentValue, 1);
console.log(product); // 输出:120
3. 数组扁平化
javascript">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. 计算数组中元素出现的次数
javascript">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. 按属性对对象数组进行分组
javascript">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 的代码实现:

javascript">// 手写 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.ppmy.cn/ops/42297.html

相关文章

2024年全国职业院校(中职组)技能大赛(ZZ052大数据应用与服务)赛项考试题库(泰迪智能科技)汇总 未完待续

2024年职业院校中职组ZZ052大数据应用与服务赛项赛题 第01套【子任务一&#xff1a;基础环境准备】答案 基础环境准备 任务内容 本实训需要使用root用户完成相关配置&#xff0c;master、slave1、slave2三台节点都需要安装JDK&#xff0c;具体要求如下&#xff1a; 将JDK安…

《TCP/IP网络编程》(第三章)地址族和数据序列

1.IP地址 IP地址是Internet Protocol&#xff08;网络协议&#xff09;的缩写&#xff0c;是为了收发网络数据而分配给计算机的值&#xff0c;分为两类&#xff1a;IPv4和IPv6&#xff0c;差别主要是表示IP地址所用的字节数&#xff0c;前者用四字节地址族&#xff0c;后者用1…

基于springboot+vue的学生考勤管理系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

前端基础入门三大核心之HTML篇:编织互联网的基石

前端基础入门三大核心之HTML篇&#xff1a;编织互联网的基石 一、HTML&#xff1a;互联网的骨架1.1 HTML基本概念1.2 第一个HTML页面1.3 标签与属性 二、HTML结构深入2.1 文档结构2.2 常用标签与实践 三、HTML5新特性四、实际开发中的应用与技巧4.1 语义化的重要性4.2 CSS与Jav…

前后端编程语言和运行环境的理解

我已重新检查了我的回答,并确保信息的准确性。以下是常用的编程语言,以及它们通常用于前端或后端开发,以及相应的框架和运行环境: 前端开发 JavaScript 框架:React, Angular, Vue.js, Ember.js, Backbone.js运行环境:Web 浏览器HTML (HyperText Markup Language) 不是编…

【数学】泰勒公式

目录 引言 一、泰勒公式 1.泰勒公式及推导 &#xff08;1&#xff09;推导 &#xff08;2&#xff09;公式 2.泰勒中值定理 &#xff08;1&#xff09;定理1&#xff08;佩亚诺余项&#xff09; &#xff08;2&#xff09;定理2&#xff08;拉格朗日余项&#xff09; …

编译Qt5.15.13

Windows 一、下载源代码&#xff0c;解压 二、安装软件 1、编译工具msvc&#xff0c;cmake&#xff0c;python3&#xff0c;jom 2、依赖库&#xff08;用于编译QSSL模块&#xff09; 2.1下载openssl 1.1源码并编译 Win10_64bit源码nmake方式安装OpenSSL_nmake安装-CSDN博…

sam代码简析

Segment Anything&#xff1a;建立了迄今为止最大的分割数据集&#xff0c;在1100万张图像上有超过1亿个掩码&#xff0c;模型的设计和训练是灵活的&#xff0c;其重要的特点是Zero-shot(零样本迁移性)转移到新的图像分布和任务&#xff0c;一个图像分割新的任务、模型和数据集…