100个使用Arrary.prototype.reduce()函数的场景

对于Array.prototype.reduce()函数我认为是es6给数组增加的最最牛逼的方法,总会在一些复杂逻辑中你会想到它可以帮你解决问题,但总是就差那么一点点感觉写不出来或者不能一下写出来。然后就呼救大佬,大佬来了简单施展一下五年功力轻松搞定,你一看就就就是他,想拧大腿一样的后悔就差一点了,诶呀下次遇见必须搞出来。我来分享一下100个我使用了reduce()函数的场景,培养一下感觉。

1. IP段处理

首先我拿到的数据是这样子的,一个对象数组,每个对象内部是起始IP,结束IP以及这段Ip当中可用的范围。

[
    {
        "id": "513",
        "name": "test",
        "startIp": "10.19.144.100",
        "endIp": "10.19.144.200",
        "netmask": "255.255.255.0",
        "gateway": "10.19.144.1",
        "usable": 100,
        "total": 101,
        "usableFields": [
            "10.19.144.100",
            "10.19.144.102-10.19.144.200"
        ]
    },
    {
        "id": "533",
        "name": "test2",
        "startIp": "10.19.120.100",
        "endIp": "10.19.120.101",
        "netmask": "255.255.255.0",
        "gateway": "10.19.120.1",
        "usable": 1,
        "total": 2,
        "usableFields": [
            "10.19.120.100"
        ]
    },
    {
        "id": "574",
        "name": "test3",
        "startIp": "10.19.130.100",
        "endIp": "10.19.130.120",
        "netmask": "255.255.255.0",
        "gateway": "10.19.130.1",
        "usable": 21,
        "total": 21,
        "usableFields": [
            "10.19.130.100-10.19.130.120"
        ]
    },
]

那我需要做成的效果如图,一个级联效果,那级联的数据结构我肯定是清楚的,看一眼就知道较难处理的主要是子级里面要展示的所有可用IP,数据中只返回了可用的IP范围。
请添加图片描述
如果是你第一想法是用什么做?我当时的第一想法是可定得用函数式编程了,上recude()分分钟解决了,那下面看我操作。

initIpCascData() {
	this.ipCascData = ipList.map((x) => ({
		label: `网段名称${x.startIp}/${x.endIp}.split('.')[3]`,
		value: x.id,
		children: [...x.usableFields.reduce((p, c) => { p.concat(this.formatIpData(c)) }, [])],
	}))
}

// 返回可用Ip段
formatIpData(str) {
    const usableIps = [];
    if (str.includes('-')) {
        const result = str.split('-');
        const start = this.ipToNum(result[0]); // 将起始ip转为数字遍历时方便
        const end = this.ipToNum(result[1]);

        for (let i = start; i <= end; i++) {
            // 添加对象时再转会成ip
            const tempObj = { label: this.numToIp(i), value: this.numToIp(i) };
            usableIps.push(tempObj);
        }
    } else {
        // 仅有一条可用
        usableIps.push({ label: str, value: str });
    }
    return usableIps;
},

调用formatIpData()方法,接收一个IP范围,返回一个数组是这个范围的全部IP值。usableFields中可能会有多个IP范围,通过reduce记录的p,再加上concat就可以将所有结果拼在一起,不得不说reduce()牛逼。

2. 遍历对象数组中某一数组属性,生成新的对象数组。

标题有点绕,看下数据结构就知知道了。后端返回一个对象数组,每个对象中有一个属性processList,累计processList中元素的加合。

// 传入的数据结构
const arr1 = [
  {
    processList: [
      { id: '100000', processId: '1016', processName: '设备激活调试' },
      { id: '100000', processId: '1008', processName: '混泥土浇筑' },
      { id: '100000', processId: '1012', processName: '机箱安装' },
    ],
  },
  {
    processList: [
      { id: '100002' ,processId: '1016', processName: '设备激活调试' },
      {  id: '100002', processId: '1008', processName: '混泥土浇筑' },
      {  id: '100002', processId: '1012', processName: '机箱安装' },
      {  id: '100002', processId: '1014', processName: '设备安装' },
      {  id: '100002', processId: 'ele_route', processName: '取电路由' },
    ],
  },
];

// 传出的数据结构
[
  { "processId": "1016", "positionIdList": ["100000", "100002"]},
  { "processId": "1008", "positionIdList": ["100000","100002"]},
  { "processId": "1012", "positionIdList": ["100000","100002"]},
  { "processId": "1014", "positionIdList": ["100002"]},
  {"processId": "ele_route", "positionIdList": ["100002"]}
]

累加,返回新数组就让我想到reduce。每次累加时还要遍历processList属性中,在新数组找是否存在当前processId。时间复杂度听到的,但目前也没想到别的写法。

reduceProcess() {
 return arr1.reduce((p, c) => {
    c.processList.forEach((x) => {
      const tempObj = p.find((y) => x.processId === y.processId);
      if (tempObj) {
        tempObj.count += 1;
        tempObj.positionIdList.push(c.id);
      } else {
        p.push({
          ...x,
          count: 1,
          positionIdList: [c.id],
        });
      }
    });
    return p;
  }, []);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值