JavaScript - 数组对象中实用好玩的reduce方法

         JavaScript中reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。

        语法:

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

        参数配置:

参数名描述
callback执行数组中每个值 (如果没有提供  initialValue则第一个值除外)的函数,包含四个参数 
        accumulator累计器累计回调的返回值; 它是上一次调用回调时返回的累积值,或initialValue(见于下方)。
        currentValue数组中正在处理的元素。
        index数组中正在处理的当前元素的索引。 如果提供了 initialValue,则起始索引号为0,否则从索引1起始。(可选)
        array调用 reduce()的数组(可选)
initialValue可选。传递给函数的初始值

        对于reduce()方法,很多人不太了解,其实熟悉之后会发现它可以应用在很多场景中。

一、数值类型

1.1 求和

         最常见的则是通过reduce()方法进行求和处理,将每次求的和,传递给下一个迭代函数中继续处理。代码如下:

const total = [10, 20, 5, 8, 10, 120, 89].reduce((total, value) => total + value, 0)
console.log('total:', total)

        运行结果如下图:

1.2 求最小值

        结合Math.min()获取数组中最小值,默认值为数组第一位数值,将每次获取的最小值返回,传递给下一个迭代的回调函数中继续处理。代码如下:

const minValue = [10, 20, 5, 8, 10, 120, 89].reduce((minVal, value) => Math.min(minVal, value), 10)
console.log('min:', minValue)

        运行结果如下较:

1.3 求最大值

        结合Math.max()获取数组中最大值,默认值为数组第一位数值,将每次获取的最大值返回,传递给下一个迭代的回调函数中继续处理。代码如下:

const maxValue = [10, 20, 5, 8, 10, 120, 89].reduce((maxVal, value) => Math.max(maxVal, value), 10)
console.log('max:', maxValue)

        结果如下图:

1.4 数组去重

        可以通过reduce()方法,对数组进行去重处理。默认传入空数组,每次回调函数执行判断空数组中是否存在该值,不存在则追加,并返回newArr到下个迭代的回调函数中继续处理。代码如下:

const arr = [10, 20, 5, 8, 10, 20, 10, 120, 89].reduce((newArr, value) => {newArr.indexOf(value) === -1 && newArr.push(value)return newArr}, [])
console.log('arr:', arr)

        运行结果如下图:

1.5 排序(升序)

        对数组升序排序,结合Array.filter方法过滤出还未参与判断最小值的数据,再使用Math.min获取过滤出来数组中最小值即可,代码如下:

const arr = [10, 20, 5, 8, 120, 89].reduce((newArr, value, index, arr) => {// 过滤年上次处理过的数据const filter = arr.filter(item => !newArr.includes(item))// 获取过滤后数组中最小值const minValue = filter.reduce((min, val) => Math.min(min, val), filter[0])// 追加到新数组中newArr.push(minValue)return newArr}, [])
console.log('arr:', arr)

        运行后结果如下图:

1.6 排序(降序)

        降序的处理和升序方法一致,只是将求最小值换成求最大值即可,代码如下:

const arr = [10, 20, 5, 8, 120, 89].reduce((newArr, value, index, arr) => {// 过滤年上次处理过的数据const filter = arr.filter(item => !newArr.includes(item))// 获取过滤后数组中最小值const maxValue = filter.reduce((max, val) => Math.max(max, val), filter[0])// 追加到新数组中newArr.push(maxValue)return newArr}, [])
console.log('arr:', arr)

        运行后结果如下图:

1.7 求平均值

        求平均值方法,则是先求和,当迭代到最后一位数值时,求出总和并除以数组长度,则得出了该数组的平均值,代码如下:

const avg = [10, 20, 5, 8, 120, 89].reduce((total, value, index, arr) => {// 当非最后一位数值,返回其和,若是最的一位则求和后除以数组长度 求出平均值return index == arr.length - 1 ? (total + value) / arr.length : total + value}, 0)
console.log('avg:', avg)

        运行后结果如下图:

二、字符串类型

2.1 拼接字符串

        数组中对于字符串拼接处理,可以通过Array.join()方法来实现,但是reduce()方法也可以实现字符串拼接,代码如下:

const conctStr = ['apple', 'banner', 'pear', 'orange'].reduce((total, value, index, arr) => {return index === 0 ? total + value : total + ',' + value}, '')
console.log('string: ', conctStr)

        运行结果如下图:

三、数组类型

3.1 扁平化 

        在JavaScript中对数组的扁平化处理,可以通过Array.flat()方法处理,这里将通过reduce()来实现对二维数组的扁平化处理。

3.1.1 二维数组

        先将默认值传入一个空数组,在每次迭代执行回调函数的时候,判断其value为数组还是正常数值,进行归类处理。代码如下:

const newArr = [[1, 3], 50, [80, 100, 23], [32, 15], 39, 23, 1].reduce((newArr, value) => {// 如果为数组,则拼接数组并返回if(Array.isArray(value)) return newArr.concat(value)// 其他则追加到数组中即可newArr.push(value)return newArr}, [])
console.log('arr: ', newArr)

        运行后代码如下图:

3.1.2 多维数组

        上面是对二维数组进行扁平化处理,但是如果遇到更深层次的多维数组,则需要通过递归方法来实现。代码如下:

// 递归处理 多维数组
function flat(arr, prev){arr.forEach(item => {if(Array.isArray(item)) prev = flat(item, prev)else prev.push(item)})return prev
}const newArr = [[1, 3], 50, [80, 100, 23, [83, 53]], [32, 15], 39, 23, 1].reduce((newArr, value) => {// 如果为数组,则拼接数组并返回if(Array.isArray(value)) return flat(value, newArr)// 其他则追加到数组中即可newArr.push(value)return newArr}, [])
console.log('arr: ', newArr)

        运行结果如下图:

3.1.3 多维数组扁平化并去重

        如上结果可见,数组中存在重复项,当然在扁平化过程中,也可以做去重处理。代码如下:

// 递归处理 多维数组
function flat(arr, prev){arr.forEach(item => {if(Array.isArray(item)) prev = flat(item, prev)else if(prev.indexOf(item) === -1) prev.push(item)})return prev
}const newArr = [[1, 3], 50, [80, 100, 23, [83, 53]], [32, 15], 39, 23, 1].reduce((newArr, value) => {// 如果为数组,则拼接数组并返回if(Array.isArray(value)) return flat(value, newArr)// 其他则追加到数组中即可if(newArr.indexOf(value) === -1) newArr.push(value)return newArr}, [])
console.log('arr: ', newArr)

        运行结果中重复项则不存在了,如下图:

 3.2 筛选数据

        在数组对象中,可以通过Array.filter()方法来筛选出需要的数据,但通过reduce()方法也可以实现这一功能。代码如下:

const result = [{name: "Tom", age: 12},{name: "John", age: 15},{name: "Olivia", age: 14},{name: "Amelia", age: 12},{name: "Corneia", age: 13},{name: "Lily", age: 12},].reduce((nArr, item) => {item['age'] == 12 && nArr.push(item)return nArr}, [])
console.log('result', result)

        运行结果如下:

3.3 模拟map()方法

        在javascript中,数组对象的map()方法,是通过指定函数处理数组的每个元素,并返回处理后的新数组。在这通过reduce()方法也可以实现,代码如下:

// 数据
const arr = [{id: 10023,name: "John",age: 20,address: "北京市中南海",gender: '男'},{id: 10024,name: "Amerlia",age: 23,address: "北京市中南海",gender: '男'},{id: 10025,name: "Lily",age: 21,address: "北京市中南海",gender: '女'}
]
// 返回新数组
const result = arr.reduce((arr, item) => arr.concat([item]), [])
console.log('result', result)

        运行结果如下:

[{ id: 10023, name: 'John', age: 20, address: '北京市中南海', gender: '男' },{id: 10024,name: 'Amerlia',age: 23,address: '北京市中南海',gender: '男'},{ id: 10025, name: 'Lily', age: 21, address: '北京市中南海', gender: '女' }
]

四、对象类型

4.1 数组转换对象

        将二维数组中的值,通过对象的键值对的形式展示出来,代码如下:

const result = [["Tom", 12],["John", 15],["Olivia", 14],["Amelia", 12],["Corneia", 13],["Lily", 12]].reduce((obj, item) => {if(Array.isArray(item) && item.length == 2) obj[item[0]] = item[1] return obj}, {})
console.log('result', result)

        运行结果如下图:

4.2 通过key值提取数据

        例如在表格中,当用户点击“修改按钮”时,要从行数据中提取修改所需要的初始参数,如每个单独取出不仅麻烦,还容易出错。这里则可以通过reduce()方法,统一提出并组装成Object返回。代码如下:

// 表格中 行数据
const rowData = {id: 10023,name: "John",age: 20,address: "北京市中南海",gender: '男',originAddress: "山东威海",status: 1,birthday: "1988/10/30",wage: 3000
}
// 要提取的 编辑数据
const editData = ["id", "name", "age"].reduce((obj, key) => {if(rowData[key]) obj[key] = rowData[key]return obj}, {})
console.log('result', editData)

        运行结果如下图:

4.3 对象与对象合并

        在某些需求中,要将数组中每个对象元素,合并成一个Object再进行业务处理,这也可以使用reduce()方法来实现。代码如下:

// 数据
const arrList = [{id: 10023,name: "John",age: 20,gender: '男'},{address: "北京市中南海",originAddress: "山东威海"}
]
// 将每个元素合并到一个对象中
const result = arrList.reduce((obj, item) => Object.assign(obj, item), {})
console.log('result', result)

        运行结果如上图:

4.4 模拟find()方法

        在javascript中,数组对象的find() 方法返回数组中满足提供的测试函数的第一个元素的值,否则返回 undefined。

        这里则通过reduce()方法实现查询数组第一个满足条件的元素,否则返回null。代码如下:

// 数据
const arr = [{id: 10023,name: "John",age: 20,address: "北京市中南海",gender: '男'},{id: 10024,name: "Amerlia",age: 23,address: "北京市中南海",gender: '男'},{id: 10025,name: "Lily",age: 21,address: "北京市中南海",gender: '女'},
]
// 查询数组中第一个为 name为Amerlia数据
const result = arr.reduce((obj, item) => {if(null === obj && item.name == 'Amerlia') obj = itemreturn obj
}, null)
console.log('result', result)

        运行结果如下图:

        通过reduce()方法实现查询数组最后一个满足条件的元素,否则返回null。代码如下:

// 数据
const arr = [{id: 10023,name: "John",age: 20,address: "北京市中南海",gender: '男'},{id: 10024,name: "Amerlia",age: 23,address: "北京市中南海",gender: '男'},{id: 10025,name: "Lily",age: 21,address: "北京市中南海",gender: '女'},{id: 10026,name: "Amerlia",age: 19,address: "北京市中南海",gender: '男'}
]
// 查询数组中最后一个为 name为Amerlia数据
const result = arr.reduce((obj, item) => {if(item.name == 'Amerlia') obj = itemreturn obj
}, null)
console.log('result', result)

        运行结果如下图:

        获取第一个满足条件的元素,和获取最后一个满足条件的元素,实是只在obj上的区别。

  • 获取一个满足条件元素,当obj值不为null时,则后期元素都不判断了,直接返回第一次匹配上的元素即可。
  • 获取最后一个满足条件元素,不管obj值是否为null,都将判断到最后一个元素为止。

4.5 归类处理

        当一个数组中,出现多个name重名的元素,则可以通过reduce()将其归类处理。代码如下:

// 数据
const arr = [{id: 10023,name: "John",age: 20,address: "北京市中南海",gender: '男'},{id: 10024,name: "Amerlia",age: 23,address: "北京市中南海",gender: '男'},{id: 10025,name: "Lily",age: 21,address: "北京市中南海",gender: '女'},{id: 10026,name: "Amerlia",age: 19,address: "北京市中南海",gender: '男'}
]
// 归类数据
const result = arr.reduce((arr, item) => {// 当新name对应字段为undefined时,为对创建一个并赋值空数组if('undefined' === typeof arr[item.name]) arr[item.name] = []// 追加到对应分类中arr[item.name].push(item)return arr
}, [])
console.log('result', result)

        运行结果如下:

[John: [{id: 10023,name: 'John',age: 20,address: '北京市中南海',gender: '男'}],Amerlia: [{id: 10024,name: 'Amerlia',age: 23,address: '北京市中南海',gender: '男'},{id: 10026,name: 'Amerlia',age: 19,address: '北京市中南海',gender: '男'}],Lily: [{id: 10025,name: 'Lily',age: 21,address: '北京市中南海',gender: '女'}]
]

五、布尔类型

5.1 模拟every()方法

         在javascript中,数组对象的every()方法,是用来检测数值元素的每个元素是否都符合条件。其实使用reduce()方法,也可以实现其结果。

        判断数组中,是否子元素都为数组类型。代码如下:

// 数据
const numbers = [[32, 12, 8, 20],[3, 4, 19, 12, 88, 6, 9, 45],[100, 21, 59, 23, 33, 150, 39, 52],[1,6, 8, 5, 4, 2]
]
// 如果flag为true,并且item为数组类型,则返回true。如果其中一个不是数组,则返回false
const result = numbers.reduce((flag, item) => flag && Array.isArray(item), true)
console.log('result', result)

        运行结果如下图:

        将numbers数组中添加一个非数组类型数据,再查看下结果。代码如下:

// 数据
const numbers = [[32, 12, 8, 20],[3, 4, 19, 12, 88, 6, 9, 45],[100, 21, 59, 23, 33, 150, 39, 52],[1,6, 8, 5, 4, 2],10
]
// 如果flag为true,并且item为数组类型,则返回true。如果其中一个不是数组,则返回false
const result = numbers.reduce((flag, item) => flag && Array.isArray(item), true)
console.log('result', result)

        运行结果如下图:

5.2 模拟some()方法

        在javascipt中,数组对象的some()方法,是用来检测数组元素中是否有元素符合指定条件。在这也可以通过reduce()方法,来实现这一结果。

        判断数组中,子元素是否存在非数组类型元素。(注意:默认值 传false)代码如下:

// 数据
const numbers = [[32, 12, 8, 20],[3, 4, 19, 12, 88, 6, 9, 45],[100, 21, 59, 23, 33, 150, 39, 52],10,[1,6, 8, 5, 4, 2]
]
// 如是有一个元素为非数组,则返回true。
// 当flag被赋值为true后,则后续不会执行到!(Array.isArray(item)),直接返回flag结果
const result = numbers.reduce((flag, item) => flag || !(Array.isArray(item)), false)
console.log('result', result)

        运行结果如下:

        此时将数组中全部改为数组类型,再查看下结果。代码如下:

// 数据
const numbers = [[32, 12, 8, 20],[3, 4, 19, 12, 88, 6, 9, 45],[100, 21, 59, 23, 33, 150, 39, 52],[1,6, 8, 5, 4, 2]
]
// 如是有一个元素为非数组,则返回true
const result = numbers.reduce((flag, item) => flag || !(Array.isArray(item)), false)
console.log('result', result)

        运行结果如下图:

5.3 模拟includes()方法

        在javascript中,数组对象的includes()方法,是用来判断一个数组是否包含一个指定的值。这里也可以通过reduce()方法实现这一结果,代码如下:

// 数据
const numbers = [[32, 12, 8, 20],[3, 4, 19, 12, 88, 6, 9, 45],[100, 21, 59, 23, 33, 150, 39, 52],[1,6, 8, 5, 4, 2]
]
// 判断数组中是否存在100
const result = numbers.reduce((flag, item) => flag || item.indexOf(100) !== -1, false)
console.log('result', result)

        结果如下图:

        此判断逻辑,则和模拟some()方法是相似的。都是将默认值先置为false,当其中一项为true时,后续都为true,最终返回true结果。

六、自定义reduce()方法

        由此可见,reduce()方法可以使用在多种场景中,其灵活性较强,能实现千变化化的结果。而且这些丰富的api方法,是在ES6版本基础之上新增的,如果一些老项目中也希望拥有reduce()方法,则可以自行实现。代码如下:

// 实现reduce()方法
Array.prototype.myReduce = function(callback, preValue){for(var i = 0; i < this.length; i++) {// 如果上个值未定义,则默认取第一个if('undefined' === typeof preValue) {// 第一个值为默认值,从第二个值开始迭代preValue = callback(this[i], this[i + 1], i + 1, this)i++ // 迭代到下一个} else {preValue = callback(preValue, this[i], i, this)}}return preValue
}
// 求和
const result = [1, 2, 3, 4, 5].myReduce(function(total, value){return total + value
}, 0)
console.log('result', result)

        运行结果如下图:

        

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

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

相关文章

渗透学习之漏洞复现

漏洞 贷齐乐的漏洞复现RCE 贷齐乐的漏洞复现 <?php header("Content-type: text/html; charsetutf-8"); require db.inc.php;function dhtmlspecialchars($string) {if (is_array($string)) {foreach ($string as $key > $val) {$string[$key] dhtmlspecial…

【Oracle点滴积累】解决ORA-20001: Latest xml inventory is not loaded into table故障的方法

广告位招租&#xff01; 知识无价&#xff0c;人有情&#xff0c;无偿分享知识&#xff0c;希望本条信息对你有用&#xff01; 今天和大家分享在安装Oracle Critical Patch Update (Patch Number:33806138) 遇到ORA-20001: Latest xml inventory is not loaded into table故障…

广东盈致MES系统——注塑和冲压行业的智能化管理

广东注塑冲压行业MES制造执行系统是一种专门为注塑和冲压行业设计的生产管理系统&#xff0c;可以帮助企业实现生产过程的智能化管理和优化。盈致MES系统是一种常见的MES系统&#xff0c;具有以下特点和功能&#xff1a; 生产计划和调度&#xff1a;MES系统可以帮助企业进行生产…

SpringCloud网关

1.网关的作用 2.网关入门 2.1引入依赖 <dependencies><dependency><groupId>com.heima</groupId><artifactId>hm-common</artifactId><version>1.0.0</version></dependency><!--网关--><dependency><g…

SAP通过函数TR_RELEASE_REQUEST释放指定请求

一&#xff1a;不通过SE09/10释放请求号 *&---------------------------------------------------------------------* *& Report Z_TRANSPORT_REQUEST *&---------------------------------------------------------------------* *& *&----------------…

AI与人类智慧的共舞:程序员在人工智能时代的新角色

文章目录 每日一句正能量前言AI辅助编程对程序员工作的影响提高编码效率改善代码质量促进学习与成长改变工作流程潜在风险与挑战技术伦理与责任应对策略结论 程序员应重点发展的核心能力复杂系统设计能力跨学科知识整合能力与AI协作的能力创新和解决问题的能力技术领导力和团队…

ctfshow-web入门-sql注入(web206-web210)系统练习sqlmap之tamper的使用与编写

目录 1、web206 2、web207 3、web208 4、web209 5、web210 1、web206 sql需要闭合 测了一下还是会先请求 /api/getToken.php 查询语句里新增了括号&#xff0c;我们注入也需要将其闭合掉&#xff0c;就像我们闭合单引号那样&#xff0c;对于 sqlmap 它会自动对闭合点进行…

HttpSession常用方法

1.HttpSession常用方法 是在Java Servlet中用来管理会话状态的重要接口&#xff0c;它提供了一种在多个请求或页面之间存储用户特定信息的方式。以下是一些 HttpSession 常用的方法和用法&#xff1a; 获取会话对象&#xff1a; HttpSession session request.getSession();…

三十八、大数据技术之Kafka3.x(1)

&#x1f33b;&#x1f33b; 目录 一、Kafka 概述1.1 定义1.2 消息队列1.2.1 消息队列内部实现原理1.2.2 传统消息队列的应用场景1.2.3 消息队列的两种模式 1.3 Kafka 基础架构 二、 Kafka 快速入门2.1 安装前的准备2.2 安装部署2.2.1 集群规划2.2.2 单节点或集群部署2.2.3 集群…

浙大数据结构慕课课后题(04-树5 Root of AVL Tree)

题目要求&#xff1a; AVL 树是一种自平衡的二叉搜索树。在 AVL 树中&#xff0c;任何节点的两个子子树的高度最多相差一;如果在任何时候它们相差不止一&#xff0c;则进行重新平衡以恢复此属性。图 1-4 说明了旋转规则。 图1 图2 图3 图4 现在给定一系列插入&#xff0c;您应该…

【经验总结】ShardingSphere5.2.1 + Springboot 分库分表 快速开始

Sharding Sphere 官方文档地址&#xff1a; https://shardingsphere.apache.org/document/current/cn/overview/maven仓库&#xff1a;https://mvnrepository.com/artifact/org.apache.shardingsphere/shardingsphere-jdbc 官方的文档写的很详尽到位&#xff0c;这里会截取部分…

Spring事务管理:程序化 vs 声明式

Spring事务管理&#xff1a;程序化 vs 声明式 1、程序化事务管理2、声明式事务管理3、总结 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; Spring框架为事务管理提供了两种主要方式&#xff1a;程序化事务管理和声明式事务管理。 1、程序化…

【数据结构】六、图:3.十字链表、邻接多重表、边集数组

3.十字链表&#xff08;有向图&#xff09; 文章目录 3.十字链表&#xff08;有向图&#xff09;3.1性能分析 4.邻接多重表&#xff08;无向图&#xff09;4.1性能分析 5.边集数组 十字链表是有向图的一种链式存储结构。 不足 对于有向图来说&#xff0c;邻接表是有缺陷的。了…

Go语言fmt包中print相关方法

Go语言的fmt包提供了多种打印相关的函数&#xff0c;主要用于在控制台或其他输出目标上格式化并输出数据。下面是一些常用的print相关方法的用途和区别&#xff1a; 1.fmt.Print() 功能: fmt.Print() 将参数的内容按默认格式输出到标准输出&#xff08;通常是控制台&#xff…

【从零开始一步步学习VSOA开发】发布订阅服务端

发布订阅服务端 概念 **发布订阅模式&#xff08;Publish-Subscribe Pattern&#xff09;**是一种消息传递模式&#xff0c;其中发布者发布消息&#xff0c;而订阅者接收和处理这些消息。它是一种松耦合的通信方式&#xff0c;允许发布者和订阅者在不知道彼此存在的情况下进行…

【C++】面向对象三大特性之—— 多态(从底层带你理解多态)

目录 前言 什么是多态 多态的定义及实现 虚函数 虚函数的重写 多态的构成条件 虚函数重写的两个例外 协变 析构函数的重写&#xff08;重要&#xff01;&#xff01;&#xff01;&#xff09; override 和 final&#xff08;了解&#xff09; override final 重载、…

linux 查看端口占用并处理

lsof 命令 lsof -i:端口注意pid netstat 命令 netstat -tnpla | grep 端口注意pid 查看详情 ps -ef | grep 3766607删除 kill -9 PIDkill -9 3766607

【整数规划】+【0—1规划】解决优化类问题(Matlab代码)

目录 文章目录 前言 一、整数规划 分类&#xff1a; 二、典例讲解 1.背包问题 2.指派问题 总结 前言 如果觉得本篇文章还不错的话&#xff0c;给作者点个赞鼓励一下吧&#x1f601;&#x1f601;&#x1f601; 在规划问题中&#xff0c;有些最优解可能是分数或小数&am…

SpringBoot+Vue3+SSE实现实时消息语音播报

目录 1、前言 2、什么是SSE 2.1、与WebSocket有什么异同&#xff1f; 3、代码实现 3.1、前置代码 3.2、SSE相关代码 3.3、消息类相关代码 3.4 、前端代码 4、实机演示 1、前言 有这样一个业务场景&#xff0c;比如有一个后台管理系统&#xff0c;用来监听订单的更新&…

【NUCLEO-G071RB】010——TIM6-基本定时器

NUCLEO-G071RB&#xff1a;010——TIM6-基本定时器 基本定时器设计目标芯片配置程序修改运行测试 基本定时器 基本定时器只能用于计时&#xff0c;可以配置有无上溢出中断&#xff0c;它基本到不支持下溢出中断。它的时钟源&#xff08;应该&#xff09;是TPCLK&#xff0c;内…