在实际开发中,有很多扁平化数组的需求,比如将数组let a = [{id:1,name:'小明', children:[{id:2,name:'小小'}]}]
转换为[{{id:1, name:'小明',parentId:undefined}, {id:2, name:'小小', parentId:1}]
,或者将上述后者数据格式转换为前者,其实实现代码很简单。
代码如下:
前者转后者:
let test1 = [
{
id: 1,
name: '小明',
children: [
{
id: 12,
name: '小张',
children: [
{
id: 123,
name: '小黄'
}
]
},
{
id: 23,
name: '小霄'
}
]
}
];
treeToArray(test1);
// 输出如下对象:
// 0: {id: 1, name: "小明", parentId: undefined}
// 1: {id: 12, name: "小张", parentId: 1}
// 2: {id: 123, name: "小黄", parentId: 12}
// 3: {id: 23, name: "小霄", parentId: 1}
function treeToArray(data) {
return data.reduce(function onReduce(init, cur) {
init.push({
id: cur.id,
name: cur.name,
parentId: cur.parentId
});
cur.children &&
cur.children.forEach(v => {
v.parentId = cur.id;
// 如果使用Vue等框架,建议如此使用递归,否则此处可替换为arguments.callee(init, v)
onReduce(init, v);
});
return init;
}, []);
}
后者转前者:
let test2 = [
{ id: 1, name: '小明', parentId: undefined },
{ id: 12, name: '小张', parentId: 1 },
{ id: 123, name: 'abc', parentId: 12 },
{ id: 23, name: 'qqq', parentId: 1 },
{ id: 888, name: '小羊', parentId: undefined },
{ id: 555, name: '小小', parentId: 123 }
];
arrayToTree(test2); // 可自行打印结果
function arrayToTree(data) {
return data.reduce(function (init, cur, _, arr) {
cur.children = arr.filter(v => v.parentId === cur.id);
!cur.parentId && init.push(cur);
return init;
}, []);
}
说明一下后者转前者的方法,因为每次init.push(cur)
只是塞进了当前对象的地址,而后续循环会添加每个对象的children
属性,并不会影响对象的地址,因此最终形成一个树状结构。