給定這個物件陣列:
[
{
"id": 1942,
"label": "1",
"url": "",
"homepage": false,
"visible": true,
"order": 1
},
{
"id": 1943,
"label": "a",
"url": "",
"parentId": 1942,
"homepage": false,
"visible": true,
"order": 1
},
{
"id": 1944,
"label": "aa",
"url": "",
"parentId": 1942,
"homepage": false,
"visible": true,
"order": 2
},
{
"id": 1945,
"label": "aaa",
"url": "",
"parentId": 1942,
"homepage": false,
"visible": true,
"order": 3
},
{
"id": 1946,
"label": "a1",
"url": "",
"parentId": 1943,
"homepage": false,
"visible": true,
"order": 1
},
{
"id": 1947,
"label": "a2",
"url": "",
"parentId": 1943,
"homepage": false,
"visible": true,
"order": 2
},
{
"id": 1948,
"label": "2",
"url": "",
"homepage": false,
"visible": true,
"order": 2
},
{
"id": 1949,
"label": "b",
"url": "",
"parentId": 1948,
"homepage": false,
"visible": true,
"order": 1
},
{
"id": 1950,
"label": "b1",
"url": "",
"parentId": 1949,
"homepage": false,
"visible": true,
"order": 1
},
{
"id": 1951,
"label": "bb",
"url": "",
"parentId": 1948,
"homepage": false,
"visible": true,
"order": 2
},
{
"id": 1952,
"label": "b2",
"url": "",
"parentId": 1949,
"homepage": false,
"visible": true,
"order": 2
}
]
我需要創建一個帶有基于父子關系的鏈接的選單。
我需要的新陣列必須具有以下物件結構。
1
1個/個
1個/個
1 / aaa
1 / a / a1
1 / a / a2
2
2 / b
2 / bb
2 / b / b1
2 / b / b2
我嘗試過沒有運氣的遞回:
convert(array) {
const x = array
.filter((m, i) => m.id === array[i].parentId)
.map((menuItem) => ({
parent: menuItem,
children: convert(array),
}));
console.log(x)
}
我嘗試使用回圈,但這種方法只能獲得有限的水平,我需要無限的深度。
convert() {
let parents = array.filter((p) => !p.parentId);
const children = array.filter((c) => c.parentId);
let combined = [];
for (var i = 0; i < parents.length; i ) {
for (var j = 0; j < children.length; j ) {
if (children[j].parentId === parents[i].id) {
combined.push([parents[i], children[j]]);
}
}
}
console.log(combined);
}
編輯: 我能夠做到 3 級深。但是對于“無限”級別的遞回,無法弄清楚。
convert() {
let parents = this.config.menuItems.filter((p) => !p.parentId);
const children = this.config.menuItems.filter((c) => c.parentId);
let combined = [];
for (var i = 0; i < parents.length; i ) {
for (var j = 0; j < children.length; j ) {
if (children[j].parentId === parents[i].id) {
combined.push([parents[i], children[j]]);
}
for (var k = 0; k < children.length; k ) {
if (children[j].id === children[k].parentId && parents[i].id === children[j].parentId) {
combined.push([parents[i], children[j], children[k]]);
}
}
}
}
console.log(combined);
}
uj5u.com熱心網友回復:
這是我認為可能有效的遞回方法。如果您不想使用 ,page_children_map
可以替換page_children_map.get(page.id)
為pages.filter(({ parentId }) => parentId === page.id)
.
const pages = [{"id":1942,"label":"1","url":"","homepage":false,"visible":true,"order":1},{"id":1943,"label":"a","url":"","parentId":1942,"homepage":false,"visible":true,"order":1},{"id":1944,"label":"aa","url":"","parentId":1942,"homepage":false,"visible":true,"order":2},{"id":1945,"label":"aaa","url":"","parentId":1942,"homepage":false,"visible":true,"order":3},{"id":1946,"label":"a1","url":"","parentId":1943,"homepage":false,"visible":true,"order":1},{"id":1947,"label":"a2","url":"","parentId":1943,"homepage":false,"visible":true,"order":2},{"id":1948,"label":"2","url":"","homepage":false,"visible":true,"order":2},{"id":1949,"label":"b","url":"","parentId":1948,"homepage":false,"visible":true,"order":1},{"id":1950,"label":"b1","url":"","parentId":1949,"homepage":false,"visible":true,"order":1},{"id":1951,"label":"bb","url":"","parentId":1948,"homepage":false,"visible":true,"order":2},{"id":1952,"label":"b2","url":"","parentId":1949,"homepage":false,"visible":true,"order":2}];
const page_children_map = pages.reduce(
(acc, val) => {
if(!val.parentId) return acc;
let arr = acc.get(val.parentId);
if(!arr) acc.set(val.parentId, arr = []);
arr.push(val);
return acc;
},
new Map()
);
const page_paths = (page, parent_list = []) => {
let paths = [];
const list = [...parent_list, page];
const children = page_children_map.get(page.id);
paths.push(list);
if(children?.length)
paths.push(...children.flatMap((child) => page_paths(child, list)));
return paths;
};
const res = pages
.filter(({ parentId }) => !parentId)
.reduce((acc, val) => {
acc.push(...page_paths(val));
return acc;
}, [])
.map( (crumbs) => crumbs.map(({ label }) => label).join(' / ') );
console.log(res);
uj5u.com熱心網友回復:
一個相當簡單的遞回:
const flat = [{"homepage": false, "id": 1942, "label": "1", "order": 1, "url": "", "visible": true}, {"homepage": false, "id": 1943, "label": "a", "order": 1, "parentId": 1942, "url": "", "visible": true}, {"homepage": false, "id": 1944, "label": "aa", "order": 2, "parentId": 1942, "url": "", "visible": true}, {"homepage": false, "id": 1945, "label": "aaa", "order": 3, "parentId": 1942, "url": "", "visible": true}, {"homepage": false, "id": 1946, "label": "a1", "order": 1, "parentId": 1943, "url": "", "visible": true}, {"homepage": false, "id": 1947, "label": "a2", "order": 2, "parentId": 1943, "url": "", "visible": true}, {"homepage": false, "id": 1948, "label": "2", "order": 2, "url": "", "visible": true}, {"homepage": false, "id": 1949, "label": "b", "order": 1, "parentId": 1948, "url": "", "visible": true}, {"homepage": false, "id": 1950, "label": "b1", "order": 1, "parentId": 1949, "url": "", "visible": true}, {"homepage": false, "id": 1951, "label": "bb", "order": 2, "parentId": 1948, "url": "", "visible": true}, {"homepage": false, "id": 1952, "label": "b2", "order": 2, "parentId": 1949, "url": "", "visible": true}]
const nest = (xs, parent = undefined) =>
xs .filter (({parentId}) => parentId == parent)
.map ((p) => ({...p, children: nest (xs, p .id)}))
console .log (nest (flat))
.as-console-wrapper {max-height: 100% !important; top: 0}
這可能會創建一個稍微不同版本的物件,與原始物件基本相同,具有嵌套children
節點。我發現這是最簡單的格式。
但是,如果您希望每個級別都有節點parent
,children
那么您可以簡單地將該函式的最后一行替換為:
.map ((p) => ({parent: p, children: nest (xs, p .id)}))
如果您對空節點感到困擾,children
排除它們會稍微復雜一些,但還不錯:
const flat = [{"homepage": false, "id": 1942, "label": "1", "order": 1, "url": "", "visible": true}, {"homepage": false, "id": 1943, "label": "a", "order": 1, "parentId": 1942, "url": "", "visible": true}, {"homepage": false, "id": 1944, "label": "aa", "order": 2, "parentId": 1942, "url": "", "visible": true}, {"homepage": false, "id": 1945, "label": "aaa", "order": 3, "parentId": 1942, "url": "", "visible": true}, {"homepage": false, "id": 1946, "label": "a1", "order": 1, "parentId": 1943, "url": "", "visible": true}, {"homepage": false, "id": 1947, "label": "a2", "order": 2, "parentId": 1943, "url": "", "visible": true}, {"homepage": false, "id": 1948, "label": "2", "order": 2, "url": "", "visible": true}, {"homepage": false, "id": 1949, "label": "b", "order": 1, "parentId": 1948, "url": "", "visible": true}, {"homepage": false, "id": 1950, "label": "b1", "order": 1, "parentId": 1949, "url": "", "visible": true}, {"homepage": false, "id": 1951, "label": "bb", "order": 2, "parentId": 1948, "url": "", "visible": true}, {"homepage": false, "id": 1952, "label": "b2", "order": 2, "parentId": 1949, "url": "", "visible": true}]
const nest = (xs, parent = undefined) =>
xs .filter (({parentId}) => parentId == parent)
.map ((p, _, __, kids = nest (xs, p.id)) => ({
...p,
...(kids .length ? {children: nest (xs, p.id)} : {})
}))
console .log (nest (flat))
.as-console-wrapper {max-height: 100% !important; top: 0}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/470055.html
標籤:javascript 数组 打字稿 递归