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

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.

相关推荐
热点推荐
彻底倒向美囯?拒绝中方移民,驱离中方工人,中方大怒:永不合作

彻底倒向美囯?拒绝中方移民,驱离中方工人,中方大怒:永不合作

星辰故事屋
2024-04-27 19:04:44
山西晋城警方通报“女子吃夜宵遭醉酒男殴打”:嫌疑人已被拘留

山西晋城警方通报“女子吃夜宵遭醉酒男殴打”:嫌疑人已被拘留

界面新闻
2024-06-12 10:28:16
章子怡戛纳拍的杂志出片了,她穿红皮衣美上天,高抬腿那张没入选

章子怡戛纳拍的杂志出片了,她穿红皮衣美上天,高抬腿那张没入选

室内设计师阿喇
2024-06-12 15:52:14
毛剑卿:18强赛该归化就归化;中国缺一个C罗,可惜只有武磊啊

毛剑卿:18强赛该归化就归化;中国缺一个C罗,可惜只有武磊啊

懂球帝
2024-06-12 21:32:08
妻子陪初恋男友法国游玩,下飞机才通知丈夫,返回后直接愣在机场

妻子陪初恋男友法国游玩,下飞机才通知丈夫,返回后直接愣在机场

局内人
2024-05-15 14:12:33
丁俊晖轰满分147分,打进2站排名赛决赛,中国一哥再冲世锦赛冠军

丁俊晖轰满分147分,打进2站排名赛决赛,中国一哥再冲世锦赛冠军

全能体育柳号
2024-06-12 07:05:09
恭喜,滕哈赫留队!曼联连追3将,总花费1.8亿欧元,冲英超冠军

恭喜,滕哈赫留队!曼联连追3将,总花费1.8亿欧元,冲英超冠军

叁炮体育
2024-06-12 10:15:34
真滴美!中国网球金花王欣瑜社媒晒多张度假照

真滴美!中国网球金花王欣瑜社媒晒多张度假照

直播吧
2024-06-12 17:37:14
全网抵制,但她又复出了

全网抵制,但她又复出了

听风听你
2024-06-10 22:36:52
贾静雯豁出去了?花苞裙长度仅到大腿,看到坐姿后网友:很可以

贾静雯豁出去了?花苞裙长度仅到大腿,看到坐姿后网友:很可以

云泽点评汇
2024-06-11 18:18:59
王思聪回应疑与黄一鸣有私生子

王思聪回应疑与黄一鸣有私生子

金陵隐士
2024-06-08 23:25:41
气象专家:40℃以上强高温范围还会进一步扩大  本轮高温天气将持续至14日

气象专家:40℃以上强高温范围还会进一步扩大 本轮高温天气将持续至14日

央广网
2024-06-12 18:40:30
违反五项纪律、涉嫌三项罪名,周斌被开除党籍

违反五项纪律、涉嫌三项罪名,周斌被开除党籍

鲁中晨报
2024-06-12 17:23:06
64岁毕福剑:定居辽宁小县城,开三轮车载客,日晒雨淋不怕累

64岁毕福剑:定居辽宁小县城,开三轮车载客,日晒雨淋不怕累

华人星光
2024-06-08 09:30:03
不回巴萨?36岁梅西确认:迈阿密是生涯最后1站!退役时间已逼近

不回巴萨?36岁梅西确认:迈阿密是生涯最后1站!退役时间已逼近

我爱英超
2024-06-13 01:38:27
这俩可能同组日本&澳大利亚均20+进球0丢球,降维打击6战全胜

这俩可能同组日本&澳大利亚均20+进球0丢球,降维打击6战全胜

直播吧
2024-06-12 10:41:10
前几年她俩都红得发紫,如今都不咋红了

前几年她俩都红得发紫,如今都不咋红了

光影纪史
2024-06-12 09:55:41
以郝子铭视角看何洁:我那“说谎成性”的前妻,凭什么能翻红

以郝子铭视角看何洁:我那“说谎成性”的前妻,凭什么能翻红

东篱畔
2024-06-10 14:27:51
高考刚结束,江西17岁男孩跳江!父母江边崩溃,网友:逼得太紧了

高考刚结束,江西17岁男孩跳江!父母江边崩溃,网友:逼得太紧了

今日搞笑分享
2024-06-12 20:48:33
美德宣布再援助2套爱国者防空系统,很快将有3套新的爱国者抵达

美德宣布再援助2套爱国者防空系统,很快将有3套新的爱国者抵达

山河路口
2024-06-12 11:41:03
2024-06-13 06:20:49
Nodejs开发
Nodejs开发
分享只有程序员懂的干货
648文章数 824关注度
往期回顾 全部

科技要闻

谁是苹果AI的“中国合伙人”?

头条要闻

顶头上司落马3周后退休副省长被查 任内曾被环保问责

头条要闻

顶头上司落马3周后退休副省长被查 任内曾被环保问责

体育要闻

国足,别辜负这场奇迹!

娱乐要闻

黄一鸣再次录视频表态孩子是王思聪的

财经要闻

徽商银行的影子 借基金向地方城投放贷?

汽车要闻

理想汽车周销量突破1万辆 单周销量首超宝马奥迪

态度原创

健康
亲子
家居
公开课
军事航空

晚餐不吃or吃七分饱,哪种更减肥?

亲子要闻

每个班都有一两个孩子患这种病,医生缺口却很大

家居要闻

原木绿居 阳光编织的自然生活诗篇

公开课

近视只是视力差?小心并发症

军事要闻

美国解禁乌克兰"亚速营"使用美制武器 俄方回应

无障碍浏览 进入关怀版