图图算法

2021-12-04  本文已影响0人  键盘上敲音符

数组聚合

需求

当我们有一个一维数组,我们希望把它按照某个类型聚合成二维数组;形如下面。

       // 原数组
        let arr = [{
                title: '一 1测试',
                id: 1
            },
            {
                title: '一 2测试',
                id: 1
            },
            {
                title: '一 3测试',
                id: 1
            },
            {
                title: '一 4测试',
                id: 1
            },
            {
                title: '二 1测试',
                id: 2
            },

        ]
        // 算法后的数组
        let newArr = [{
                "title": "一",
                "children": [{
                        "title": "一 1测试",
                        "id": 1
                    },
                    {
                        "title": "一 2测试",
                        "id": 1
                    },
                    {
                        "title": "一 3测试",
                        "id": 1
                    },
                    {
                        "title": "一 4测试",
                        "id": 1
                    }
                ]
            },
            {
                "title": "二",
                "children": [{
                    "title": "二 1测试",
                    "id": 2
                }]
            }
        ]

解答

方法一

      let map = {},
      dest = [];
    arr.forEach((item) => {
      // 不存在这个key,给dest 数组创建了一个项,并携带子集,并给map 创建了一项
      if (!map[item.id]) {
        dest.push({
          title: item.title,
          id: item.id,
          children: [item],
        });
        // 这个id已被标记
        map[item.id] = 'flag';
      }
      // 存在这个key,代表dest 已经有了这个值了,并且
      else {
        for (let j = 0; j < dest.length; j++) {
          let dj = dest[j];
          // 这个判断很重要,当前项已经在dest数组存在,所以要循环dest数组,找到匹配项,然后不找了
          if (item.id == dj.id) {
            dj.children.push(item);
            break;
          }
        }
      }
    });

方法二

let map = {},
      dest = [];
    arr.forEach((item) => {
      // 不存在这个key,给dest 数组创建了一个项,并携带子集,并给map 创建了一项
      if (!map[item.id]) {
        dest.push({
          title: item.title,
          id: item.id,
          children: [item],
        });
        // 这个id已被标记
        map[item.id] = 'flag';
      }
      // 存在这个key,代表dest 已经有了这个值了,并且
      else {
        let dj = dest.find(j => j.id == item.id)
        dj.children.push(item)
      }
    });
    console.log(dest);

思考:巧妙的地方在于利用对象只有唯一的key,来建立类型;一开始循环的时候,肯定没有任何类型,那么就创建一个类型,并且把这条数据放到新的数组中。第二次循环的时候,遇到了这个类型。那么去循环新的数组。通过类型比较,找到这个类型,然后在此类型的子集下添加当前项,跳出循环

递归

曾多次能看到敞开大门乘客们的科目曾多次

上一篇 下一篇

猜你喜欢

热点阅读