API 回傳陣列和物件的嵌套資料結構。資料以樹狀物件的形式出現,每個物件都有可能的父子關系。下面的示例代碼顯示了結構本身。
[{
label: "search me",
value: "searchme",
children: [{
label: "search me too",
value: "searchmetoo",
children: [{
label: "No one can get me",
value: "anonymous",
}],
}],
}, {
label: "search me2",
value: "searchme2",
children: [{
label: "search me too2",
value: "searchmetoo2",
children: [{
label: "No one can get me2",
value: "anonymous2",
}],
}],
}]
必須將上述資料轉換為物件的(平面)陣列,其中每個物件將表示以前的節點元素,但具有唯一的主鍵 (id)。此外,除了沒有父節點的根節點之外,節點的父 ID 等于其父節點的 ID(主鍵),因此父 ID 應該為空。
上面提供的源資料的目標結構然后匹配以下代碼......
[{
id: 1, // DIAGID
parentId: null, // PARENTID
label: "search me", // DIAGNOSIS
value: "searchme" // DIAGTYPE
}, {
id: 2,
parentId: 1,
label: "search me too",
value: "searchmetoo"
}, {
id: 3,
parentId: 2,
label: "No one can get me",
value: "anonymous"
}, {
id: 4,
parentId: null,
label: "search me2",
value: "searchme2"
}, {
id: 5,
parentId: 4,
label: "search me too2",
value: "searchmetoo2"
}, {
id: 6,
parentId: 5,
label: "No one can get me2",
value: "anonymous2"
}]
uj5u.com熱心網友回復:
您可以采用遞回方法Array#flatMap并parent為下一次呼叫存盤。
這種方法id對所有節點都遞增。
const
flatTree = (id => parent => ({ children = [], ...object }) => [
{ id: id, ...object, parent },
...children.flatMap(flatTree(id))
])(0),
tree = [{ label: 'search me', value: 'searchme', children: [{ label: 'search me too', value: 'searchmetoo', children: [{ label: 'No one can get me', value: 'anonymous' }] }] }, { label: 'four', searchme: '4four' }],
flat = tree.flatMap(flatTree(null));
console.log(flat);
.as-console-wrapper { max-height: 100% !important; top: 0; }
uj5u.com熱心網友回復:
這是一個遞回函式dfs,它通過輸入樹執行預序遍歷,并傳遞一個計數器,該計數器提供id將在輸出中使用的屬性。還id傳遞當前節點的parentId遞回呼叫:
const dfs = ({children=[], ...node}, counter={id: 1}, parentId=null) =>
[{ ...node, id: counter.id , parentId}].concat(
children.flatMap(child => dfs(child, counter, node.id))
);
const response = {"label":"search me","value":"searchme","children":[{"label":"search me too","value":"searchmetoo","children":[{"label":"No one can get me","value":"anonymous"}]}]};
const result = dfs(response);
console.log(result);
uj5u.com熱心網友回復:
這個版本是特林科特和尼古拉斯凱里的想法的混搭。從 trincot 的回答(實際上回答了一個不同但密切相關的問題)我竊取了他的{ctr: id: 1}處理方式。從 Nicholas 那里,我使用生成器更輕松地遍歷值,盡管我從那里簡化了一些。
我認為它們結合起來提供了一個很好的解決方案:
const flatten = function * (xs, ctr = {id: 1}, parent = null) {
for (let {children = [], ...x} of xs) {
const node = {id: ctr .id , parentId: parent ? parent .id : null, ...x}
yield node
yield * flatten (children, ctr, node)
}
}
const transform = (xs) => [...flatten (xs)]
const response = [{label: "search me", value: "searchme", children: [{label: "search me too", value: "searchmetoo", children: [{label: "No one can get me", value: "anonymous"}]}]}, {label: "search me2", value: "searchme2", children: [{label: "search me too2", value: "searchmetoo2", children: [{label: "No one can get me2", value: "anonymous2"}]}]}]
console .log (transform (response))
.as-console-wrapper {max-height: 100% !important; top: 0}
uj5u.com熱心網友回復:
我想說遞回樹遍歷就是你所需要的,但你可以用生成器輕松完成同樣的事情:
function *visitNodes( root, parent = null, id = 0 ) {
const node = {
...root,
id : id,
parentId = parent ? parent.id : null
};
delete node.children;
yield node;
for ( const child of root.children ?? [] ) {
yield *visitNodes(child, node, id);
}
}
定義生成器后,您可以遍歷節點:
for (const node of visitNodes( tree ) ) {
// do something useful with node here
}
您可以使用擴展運算子輕松將其轉換為串列:
const nodes = [...visitNodes(tree)];
或使用Array.from():
const nodes = Array.from( visitNodes(tree) );
uj5u.com熱心網友回復:
reduce映射和收集任何專案的單個遞回實作的功能通常可以完成這項作業。
它使用一個collector物件作為reduce方法的第二個引數(和 reducer 的初始值)。所述collector的result陣列收集的任何專案。并count不斷增加并分配為收集的專案id(前DIAGID),而專案parentId(前PARENTID)根據需要更新,以始終反映當前的遞回呼叫堆疊......
function countMapAndCollectNestedItemRecursively(collector, item) {
let { count = 0, parentId = null, result } = collector;
const { children = [], ...itemRest } = item;
result.push({
id: count,
parentId,
...itemRest,
});
count = children.reduce(
countMapAndCollectNestedItemRecursively,
{ count, parentId: count, result }
).count;
return { count, parentId, result };
}
const sampleData = [{
label: "FOO",
value: "foo",
children: [{
label: "FOO BAR",
value: "fooBar",
children: [{
label: "FOO BAR BAZ",
value: "fooBarBaz",
}],
}, {
label: "FOO BIZ",
value: "fooBiz",
children: [{
label: "FOO BIZ BUZ",
value: "fooBizBuz",
}],
}],
}, {
label: "BAR",
value: "bar",
children: [{
label: "BAR BAZ",
value: "barBaz",
children: [{
label: "BAR BAZ BIZ",
value: "barBazBiz",
children: [{
label: "BAR BAZ BIZ BUZ",
value: "barBazBizBuz",
}],
}, {
label: "BAR BAZ BUZ",
value: "barBazBuz",
}],
}, {
label: "BAR BIZ",
value: "barBiz",
children: [{
label: "BAR BIZ BUZ",
value: "barBizBuz",
}],
}],
}];
console.log(
sampleData.reduce(
countMapAndCollectNestedItemRecursively,
{ result: [] },
).result
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/349176.html
標籤:javascript 数组 递归 数据结构 映射
