数组聚合
需求
当我们有一个一维数组,我们希望把它按照某个类型聚合成二维数组;形如下面。
// 原数组
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,来建立类型;一开始循环的时候,肯定没有任何类型,那么就创建一个类型,并且把这条数据放到新的数组中。第二次循环的时候,遇到了这个类型。那么去循环新的数组。通过类型比较,找到这个类型,然后在此类型的子集下添加当前项,跳出循环
递归
曾多次能看到敞开大门乘客们的科目曾多次
网友评论