mr_*_*ash 1 javascript arrays algorithm tree flatten
我有一个平面阵列。像这样:
const inputArray = [
{
path: '1',
id: '1'
},
{
path: '2',
id: '2'
},
{
path: '3',
id: '3'
},
{
path: '3.4',
id: '4'
},
{
path: '3.5',
id: '5'
},
{
path: '3.4.6',
id: '6'
},
{
path: '3.4.7',
id: '7'
},
{
path: '8',
id: '8'
},
]
Run Code Online (Sandbox Code Playgroud)
pathid 元素的唯一路径在哪里。例如,path: '3.5'表示此对象是具有 的对象的子对象id: '3'。并且path: '3.4.6'是孩子的path: '3.4'。我想将它们收集到嵌套结构中。所以结果应该是这样的。
const result = [
{
path: '1',
id: '1',
children: []
},
{
path: '2',
id: '2',
children: []
},
{
path: '3',
id: '3',
children: [
{
path: '3.4',
id: '4',
children: [
{
path: '3.4.6',
id: '6',
children: []
},
{
path: '3.4.7',
id: '7',
children: []
},
]
},
{
path: '3.5',
id: '5',
children: []
},
]
},
{
path: '8',
id: '8',
children: []
},
]
Run Code Online (Sandbox Code Playgroud)
而且我还需要第二个算法将它们从嵌套结构转换回平面结构。你能提供广告建议吗?
更新:数据未排序。这是我的尝试,但是代码太多并且在某些情况下会失败。我觉得应该有更好的方法来做到这一点。
使用Array.reduce、Array.findIndex、Array.push和Array.shift
转换为树
input array是按路径排序的,否则不会排序inputArray.sort((a,b) => a.path - b.path);addChildren需要 3 个输入
的函数t如果它在层次结构中a是最后一个,则表示是对象的有效占位符。因此,将其推到那里。如果有剩余值,则通过匹配id. 现在,再次调用 with 函数a将成为匹配对象的children数组,
保持不变,并将成为层次结构的剩余数组。ctconst inputArray = [{path:'1',id:'1'},{path:'2',id:'2'},{path:'3',id:'3'},{path:'3.4',id:'4'},{path:'3.5',id:'5'},{path:'3.4.6',id:'6'},{path:'3.4.7',id:'7'},{path:'8',id:'8'}];
const result = inputArray.reduce((a,c) => {
let t = c.path.split(".").map(Number);
addChildren(a,c,t);
return a;
}, []);
function addChildren(a, c, t) {
let val = t.shift();
if(!t.length) {
a.push({...c, children : []});
} else {
var i = a.findIndex(({id}) => Number(id) === val);
addChildren(a[i].children, c, t);
}
}
console.log(result);Run Code Online (Sandbox Code Playgroud)
压扁树
var inputArray = [{path:'1',id:'1',children:[]},{path:'2',id:'2',children:[]},{path:'3',id:'3',children:[{path:'3.4',id:'4',children:[{path:'3.4.6',id:'6',children:[]},{path:'3.4.7',id:'7',children:[]},]},{path:'3.5',id:'5',children:[]},]},{path:'8',id:'8',children:[]},];
function flattenArray(a, r) {
a.forEach(({children, ...rest}) => {
r.push(rest);
if(children) flattenArray(children, r)
});
}
var result = [];
flattenArray(inputArray, result);
console.log(result);Run Code Online (Sandbox Code Playgroud)