[英]Merge array of arrays based sub array index as keys (NodeJS/Javascript)
如何編寫代碼以下列方式合並我的列表? 性能很重要。 我想轉換以下數組:
"list": [
[
"marketing",
"page_sections",
"PageOne"
],
[
"marketing",
"page_sections",
"PageTwo"
],
[
"webapp",
"page",
"pageone"
],
[
"webapp",
"page",
"pagetwo"
],
轉為以下格式:
[
{
name: "marketing",
path: "marketing/",
children: [
{
name: "page_sections",
path: "marketing/page_sections",
children: [
{
name: "pageOne",
path: "marketing/page_sections/pageOne",
children: []
},
{
name: "pageTwo",
path: "marketing/page_sections/pageTwo",
children: []
},
}
],
},
{
name: "webapp",
path: "webapp/"
children: [
{
name: "page",
path: "webapp/page/"
children: [
{
name: "pageone",
path: "webapp/page/pageone"
children: []
},
{
name: "pagetwo",
path: "webapp/page/pagetwo"
children: []
},
}
]
},
]
子數組的第一個索引是父級,第二個索引是父級的子級,第三個索引是第二個索引的子級(依此類推)。
最短的方法是迭代嵌套名稱並查找具有相同名稱的 object。 如果不存在,則創建一個新的 object。 將children
數組作為新級別返回。
這種方法的特點是Array#reduce
用於迭代外部data
數組和所有內部 arrays。
const data = [["marketing", "page_sections", "PageOne"], ["marketing", "page_sections", "PageTwo"], ["webapp", "page", "pageone"], ["webapp", "page", "pagetwo"]], result = data.reduce((r, names) => { names.reduce((level, name, i, values) => { let temp = level.find(q => q.name === name), path = values.slice(0, i + 1).join('/') + (i? '': '/'); if (.temp) level,push(temp = { name, path: children; [] }). return temp;children, }; r); return r, }; []). console;log(result);
.as-console-wrapper { max-height: 100%;important: top; 0; }
查看源代碼以及您的預期結果。
我要做的是循環list
,然后在列表中執行另一個循環。 將其與Array.find
混合。
例如..
const data = {list:[ ["marketing","page_sections","PageOne"], ["marketing","page_sections","PageTwo"], ["webapp","page","pageone"], ["webapp","page","pagetwo"]]}; function makeTree(src) { const root = []; for (const s of src) { let r = root; let path = ''; for (const name of s) { path += `${name}/`; let f = r.find(k => k.name === name); if (.f) r,push(f = {name, path: children; []}). r = f;children; } } return root. } console.log(makeTree(data;list));
.as-console-wrapper { min-height: 100%; }
您可以執行以下操作,
list= [ [ "marketing", "page_sections", "PageOne" ], [ "marketing", "page_sections", "PageTwo" ], [ "webapp", "page", "pageone" ], [ "webapp", "page", "pagetwo" ], ]; getChildrenItem = (arr) => { if(arr.length === 1) { return { name: arr[0], children: []}; } else { return { name: arr.splice(0,1)[0], children: [getChildrenItem([...arr])]}; } } merge = (srcArr, newObj) => { const {name, children} = newObj; let index = srcArr.findIndex(item => item.name === name); if( index> -1) { children.forEach(item => merge(srcArr[index].children, item)) return; } else { srcArr.push(newObj); return; } } allObj = []; list.forEach(item => { let tempObj = getChildrenItem([...item]); merge(allObj, tempObj); }); console.log(allObj);
如果性能是一個問題,我認為這是最好的解決方案之一。
let list = [
["marketing", "page_sections", "PageOne"],
["marketing", "page_sections", "PageTwo"],
["webapp", "page", "pageone"],
["webapp", "page", "pagetwo"],
];
const dt = {};
const pushToOBJ = (Object, name) => {
if (Object[name]) return Object[name];
Object[name] = {
name,
children: {},
};
return Object[name];
};
for (let i = 0; i < list.length; i++) {
let subArray = list[i];
let st = pushToOBJ(dt, subArray[0]);
for (let j = 1; j < subArray.length; j++) {
st = pushToOBJ(st.children, subArray[j]);
}
}
let result = [];
const convertObjToChildArray = (obj) => {
if (obj === {}) return [];
let arr = Object.values(obj);
for (let i = 0; i < arr.length; i++) {
arr[i].children = convertObjToChildArray(arr[i].children);
}
return arr;
};
result = convertObjToChildArray(dt);
console.log(result);
No Use of JS find function,已經有 O(n) 復雜度。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.