网易首页 > 网易号 > 正文 申请入驻

JS数组Reduce的妙用,收藏等于学会!

0
分享至

作者:前端发现者来源:前端发现

本文转载自微信公众号「前端发现」,作者前端发现者。转载本文请联系前端发现公众号。

说到处理数组的方法,想必大家都不陌生了,今天我们一起来学习下理数组常见场景下的方法。

首先来看看 reduce 方法可以传入哪些参数

function(pre,cur,index,arr)

  • pre:必需,初始值或计算结束后的返回值
  • cur:非必需,当前处理的元素
  • index:非必需,当前处理元素的索引
  • arr:非必需,当前元素所属的数组对象

直接看看

  • const list = [1,2,3,4,5]
    const result = list.reduce(function (pre, cur, index, arr) {
    console.log('pre:' + pre, 'cur:' + cur, 'index:' + index)
    return pre + cur
    console.log(result)
    // => pre:1 cur:2 index:1
    // => pre:3 cur:3 index:2
    // => pre:6 cur:4 index:3
    // => pre:10 cur:5 index:4
    // => 15

可以看到,第一轮pre的值是数组的第一个值,然后当前处理元素直接是元素的第二个数据,索引是数组的1。第二轮的pre就是第一次逻辑处理 return pre + cur 返回的结果(即3)。以此类推...共循环4轮。

再来看个相乘的处理逻辑的:

  • const list = [1,2,3,4,5]
    const result = list.reduce(function (pre, cur, index, arr) {
    console.log('pre:' + pre, 'cur:' + cur, 'index:' + index)
    return pre * cur
    console.log(result)
    // => pre:1 cur:2 index:1
    // => pre:2 cur:3 index:2
    // => pre:6 cur:4 index:3
    // => pre:24 cur:5 index:4
    // => 120

看着这么复杂,能举个再简单的例子吗?别问,问就是有!

  • const result = list.reduce((pre, cur) => pre + cur)
    console.log(result) // => 15

简单后再来个高级点的尝鲜下。

数组去重

将数组传输之前,我们先来了解下 reduce 的另外一个,即 initialValue。它是代表传递给函数的初始值,「可以理解为给pre设置了默认的值」。

  • const list = [1,1,3,5,5,7,9]
    let arr = list.reduce((pre,cur)=>{
    if(!pre.includes(cur)){
    return pre.concat(cur)
    }else{
    return pre
    },[]) // => 给pre设置默认的空数组[]
    console.log(arr) // => [1, 3, 5, 7, 9]

可以看到list数组的长度为7,共循环7次(设置默认的空数组,导致cur第一轮是数组的第一个数据)。每循环一次就判断pre数组里存不存在当前循环的元素,若不存在则加入到pre数组去,否则就直接退出当前循环。

数组二维转一维

  • let arr = [1,2,[4, 6], [1, 6], [2, 2]]
    let newArr = arr.reduce((pre,cur)=>{
    return pre.concat(cur)
    },[])
    console.log(newArr) // => [1, 2, 4, 6, 1, 6, 2, 2]

这里其实也就是利用了数组的 concat 方法,跟上面的使用也是大同小异,理顺一下就可以理解的了。

数组多维转一维

  • let arr = [1, 2, [4, 6], [1, 6, [3, 6]], [1, [3, 4, [1, 2]], [2, 2]]]
    const newArr = (arr) => {
    return arr.reduce((pre, cur) => {
    return pre.concat(Array.isArray(cur) ? newArr(cur) : cur)
    }, [])
    console.log(newArr(arr)) // => [1, 2, 4, 6, 1, 6, 3, 6, 1, 3, 4, 1, 2, 2, 2]

这里使用了 三目运算 、 concat 数据拼接 、递归 的思路完成。先判断当前处理的元素(有可能是数组)是不是数组(Array.isArray(cur)),如果是再次执行newArr,否则就直接处理当前元素,即将cur拼接进之前处理的数组中。

计算元素出现个数

讲解这个之前我们先来回忆下for...in的用法:

for...in 声明用于对数组或者对象的属性进行循环/迭代操作。

直接上

  • var arr = ['张三','李四','王五']
    for (let x in arr)
    console.log(x)
    // => 张三
    // => 李四
    // => 王五

可以看到当arr为数组时 x 相当于 for 循环的?? 标

那当arr为对象呢?

  • const obj = {
    name: "张三",
    age: 18,
    height: "180"
    for(let key in obj){
    console.log(key)
    // => name
    // => age
    // => height

可以看到当循环的“对象”是对象时,循环的单项就是对象的属性。

所以我们可以根据这个特性来判断对象是否为数组/对象的元素/属性。

  • // 数组时判断下标
    let arr = ["a","b","2","3"]
    console.log("b" in arr) // => false
    console.log(2 in arr) // => true
    // 对象时判断属性
    let obj = {a:"a",b:"b",c:"2",d:"3"}
    console.log("b" in obj) // => true
    console.log(2 in obj) // => false

好的,回忆完这些知识,我们来看看怎么完成这个需求

  • let names = ['张三', '李四', '张三', '王五', '王五', '王五']
    let total = names.reduce((pre,cur)=>{
    if(cur in pre){
    pre[cur]++
    console.log("判断为真:")
    console.log(pre)
    }else{
    pre[cur] = 1
    console.log("判断为假:")
    console.log(pre)
    return pre
    },{})
    console.log(total); // => {张三: 2, 李四: 1, 王五: 3}

首先先传入一个{}对象,说明初始的pre为{}。那么第一轮判断if的时候就变成 '张三' in {} 很明显此时判断条件是 false 。所以就执行 else 里面的逻辑后变成:{'张三':1}。第二轮时 李四 也是如此。当第三轮时再次遇到“张三”,此时对象是 {'张三':1,'李四':1} ,所以if判断是 true ,所以张三直接+1。来看看打印情况:

  • 判断为假:
    // => {张三: 1}
    判断为假:
    // => {张三: 1, 李四: 1}
    判断为真:
    // => {张三: 2, 李四: 1}
    判断为假:
    // => {张三: 2, 李四: 1, 王五: 1}
    判断为真:
    // => {张三: 2, 李四: 1, 王五: 2}
    判断为真:
    // => {张三: 2, 李四: 1, 王五: 3}
  • 属性求和
  • const list = [
    name: '张三',
    age: 18
    },
    name: '李四',
    age: 20
    },
    name: '王五',
    age: 22

    let total = list.reduce((pre, cur) => {
    console.log(cur)
    // => {name: '张三', age: 18}
    // => {name: '李四', age: 20}
    // => {name: '王五', age: 22}
    return cur.age + pre
    }, 0)
    console.log(total) // => 60

如此是不是省了使用 map 去求和呢?更简便可以这么写:

  • let total = list.reduce((pre, cur) => cur.age + pre, 0)

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
山东济南数百家农家乐假期客流骤减,送土鸡蛋都没人拿的停车位空了一排

山东济南数百家农家乐假期客流骤减,送土鸡蛋都没人拿的停车位空了一排

小鹿姐姐情感说
2026-07-05 15:39:15
吃“春药”后,是什么感觉?医生说的2个案例,告诉你真实感受

吃“春药”后,是什么感觉?医生说的2个案例,告诉你真实感受

医学科普汇
2026-06-23 17:16:20
世预赛!中国男篮VS中国台北,3好消息1坏消息,庞峥麟有机会

世预赛!中国男篮VS中国台北,3好消息1坏消息,庞峥麟有机会

林子说事
2026-07-05 15:35:53
动物交配六亲不认,雄性遇上自己母亲怎么办?马不欺母是真的吗?

动物交配六亲不认,雄性遇上自己母亲怎么办?马不欺母是真的吗?

趣文说娱
2026-07-02 18:28:06
为什么不能干涉他人的因果?网友:有些事儿说不清楚

为什么不能干涉他人的因果?网友:有些事儿说不清楚

阿康四岁啦
2026-06-26 11:05:34
美军司令罕见摊牌:第一岛链所有武器库,最终都只为台湾而设

美军司令罕见摊牌:第一岛链所有武器库,最终都只为台湾而设

瞩望云霄
2026-07-05 22:42:01
深圳街道都开始摸底电容电阻,AI把MLCC、PCB、覆铜板全抬成硬通货了

深圳街道都开始摸底电容电阻,AI把MLCC、PCB、覆铜板全抬成硬通货了

时尚的弄潮
2026-07-05 20:51:35
世界杯带火非洲岛国佛得角,人口50多万拥有7座客运机场,当地中国人称:最近国人多了起来

世界杯带火非洲岛国佛得角,人口50多万拥有7座客运机场,当地中国人称:最近国人多了起来

时代财经
2026-07-04 20:18:23
71岁卢卡申科新伴仅22岁,常年被美女模特环绕,分居妻子杳无音信

71岁卢卡申科新伴仅22岁,常年被美女模特环绕,分居妻子杳无音信

译言
2026-06-21 07:11:28
7.6早评|炸裂!半导体大消息!A股本周能反弹?

7.6早评|炸裂!半导体大消息!A股本周能反弹?

龙行天下虎
2026-07-06 01:26:40
对于明天周一A股,我只说3句话:第一,3927点或将牢不可破!

对于明天周一A股,我只说3句话:第一,3927点或将牢不可破!

趋势清风侠
2026-07-05 10:02:47
中国人民大学通报:未发现蒋方舟存在学术不端行为,暂停其导师研究生招生资格1年

中国人民大学通报:未发现蒋方舟存在学术不端行为,暂停其导师研究生招生资格1年

扬子晚报
2026-07-05 22:25:43
男子上厕所不掀马桶圈,妻子跟擦10年后崩溃欲离婚……有医生建议:为避免家庭矛盾,男性最好是坐着上厕所

男子上厕所不掀马桶圈,妻子跟擦10年后崩溃欲离婚……有医生建议:为避免家庭矛盾,男性最好是坐着上厕所

新民周刊
2026-07-03 21:53:09
天天锻炼不等于长寿,专家忠告:年过60,只适合三种运动方式

天天锻炼不等于长寿,专家忠告:年过60,只适合三种运动方式

华庭讲美食
2026-07-02 00:12:22
彻查!信号强烈!中央升级反腐“天网”!

彻查!信号强烈!中央升级反腐“天网”!

职场资深秘书
2026-07-04 23:45:24
巅峰时期的QQ有多“狂”?2008年,腾讯竟打算用Q币给员工发工资

巅峰时期的QQ有多“狂”?2008年,腾讯竟打算用Q币给员工发工资

荆楚寰宇文枢
2026-05-14 23:20:07
58中33!自由市场第一前锋!勇士最快速度签约

58中33!自由市场第一前锋!勇士最快速度签约

篮球实战宝典
2026-07-04 21:46:46
记一个我被Claude Fable 5震撼的瞬间。

记一个我被Claude Fable 5震撼的瞬间。

数字生命卡兹克
2026-07-03 08:20:43
重磅!杜锋下课,卸任广东宏远主教练,焦泊乔或留队,徐昕迎转机

重磅!杜锋下课,卸任广东宏远主教练,焦泊乔或留队,徐昕迎转机

烨侃体育
2026-07-05 16:46:52
纯属意外!陈龙8岁儿子狂揽19个冠军,一开始只是去蹭哥哥的课

纯属意外!陈龙8岁儿子狂揽19个冠军,一开始只是去蹭哥哥的课

赏心悦目的我
2026-07-03 16:17:29
2026-07-06 03:08:49
Nodejs开发
Nodejs开发
分享只有程序员懂的干货
648文章数 823关注度
往期回顾 全部

科技要闻

华为:逻辑折叠将大幅提升麒麟CPU核心频率

头条要闻

四川深夜连发3次超4级地震 居民外出躲避回屋再遇地震

头条要闻

四川深夜连发3次超4级地震 居民外出躲避回屋再遇地震

体育要闻

姆巴佩点走巴拉圭:巴黎三代左锋传承

娱乐要闻

霉霉婚礼照片泄露 有四人违规

财经要闻

揭秘跨境“对敲”换汇黑产

汽车要闻

方程豹钛9内饰曝光 用上了长联屏设计/下半年上市

态度原创

旅游
数码
亲子
本地
公开课

旅游要闻

我们人类最早的祖先,居然出自云南这座小山,看完心生敬畏!

数码要闻

Intel Xe3P核显越来越近!Linux曝光新进展

亲子要闻

工程车爱游泳

本地新闻

国内足球之旅?这座小城给你高分答案

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版