我無法弄清楚如何正確解釋這一點,但我想制作一個采用此陣列的函式:
const tasks = [
{id: 1, goal: 'Clean apartment', parent_id: null},
{id: 2, goal: 'Clean bathroom', parent_id: 1},
{id: 3, goal: 'Clean kitchen', parent_id: 1},
{id: 4, goal: 'Clean sink', parent_id: 2},
{id: 5, goal: 'Clean shower', parent_id: 2},
{id: 6, goal: 'Make app', parent_id: null}
]
并生成此物件:
{id: 1, goal: 'Clean apartment', parent_id: null, children: [
{id: 2, goal: 'Clean bathroom', parent_id: 1, children: [
{id: 4, goal: 'Clean sink', parent_id: 2, children: []},
{id: 5, goal: 'Clean shower', parent_id: 2, children: []},
]},
{id: 3, goal: 'Clean kitchen', parent_id: 1, children: []},
]},
{id: 6, goal: 'Make app', parent_id: null, children: []}
編輯:到目前為止我做了這個,但它只回傳孩子的第一層:
function addChildren(tasks, id) {
var task = tasks.find(task => task.id === id)
var children = tasks.filter(task => task.parent_id === id)
task.children = children
return task
}
var newTask = addChildren(tasks, 1)
console.log(newTask)
編輯 2:我嘗試使函式遞回,但我收到一條錯誤訊息,說“tasks.find 不是函式”。
function addChildren(tasks, id) {
var task = tasks.find(task => task.id === id)
var children = tasks.filter(task => task.parent_id === id)
task.children = children
task.children.forEach(child => {
addChildren(child, child.id)
})
return task
}
var newTask = addChildren(tasks, 1)
console.log(newTask)
uj5u.com熱心網友回復:
使函式遞回并為每個孩子呼叫它。
const tasks = [
{id: 1, goal: 'Clean apartment', parent_id: null},
{id: 2, goal: 'Clean bathroom', parent_id: 1},
{id: 3, goal: 'Clean kitchen', parent_id: 1},
{id: 4, goal: 'Clean sink', parent_id: 2},
{id: 5, goal: 'Clean shower', parent_id: 2},
{id: 6, goal: 'Make app', parent_id: null}
]
function addChildren(tasks, idOrTask) {
var task = (typeof idOrTask === 'number') ? tasks.find(task => task.id === idOrTask) : idOrTask;
var children = tasks.filter(t => t.parent_id === task.id);
task.children = children.map(child => addChildren(tasks, child));
return task
}
var newTask = addChildren(tasks, 1)
console.log(newTask)
我已經稍微優化了函式以避免不必要的呼叫find。
uj5u.com熱心網友回復:
您可以過濾與給定 id 匹配的那些,并使用遞回呼叫計算它們的子級:
const nest = (xs, parent = null) =>
xs .filter (({parent_id}) => parent_id == parent)
.map (({id, ...rest}) => ({id, ...rest, children: nest (xs, id)}))
const tasks = [{id: 1, goal: 'Clean apartment', parent_id: null}, {id: 2, goal: 'Clean bathroom', parent_id: 1}, {id: 3, goal: 'Clean kitchen', parent_id: 1}, {id: 4, goal: 'Clean sink', parent_id: 2}, {id: 5, goal: 'Clean shower', parent_id: 2}, {id: 6, goal: 'Make app', parent_id: null}]
console .log (nest (tasks))
.as-console-wrapper {max-height: 100% !important; top: 0}
如果您不再需要parent_id輸出中的 now-redundant,只需將map上面的行替換為:
.map (({id, parent_id, ...rest}) => ({id, ...rest, children: nest (xs, id)}))
uj5u.com熱心網友回復:
const tasks = [
{id: 1, goal: 'Clean apartment', parent_id: null},
{id: 2, goal: 'Clean bathroom', parent_id: 1},
{id: 3, goal: 'Clean kitchen', parent_id: 1},
{id: 4, goal: 'Clean sink', parent_id: 2},
{id: 5, goal: 'Clean shower', parent_id: 2},
{id: 6, goal: 'Make app', parent_id: null}
]
function buildTree(root) {
return {
goal: root.goal, // Store the goal
children: tasks
.filter(task => task.parent_id === root.id) // All tasks with parent_id = root.id
.map(child => buildTree(child)) // Recursively collect their children
}
}
const result = buildTree(tasks[0]) // Build the tree starting with 'Clean apartment'
console.log(result);
您可以通過不傳遞 ID 來稍微簡化邏輯
uj5u.com熱心網友回復:
為什么需要遞回?您可以使用這種迭代方式
function buildTree(tasks) {
const tasksById = tasks.reduce((acc, task) => ({
...acc,
[task.id]: { ...task }
}), {})
return Object.values(tasksById).reduce((tree, task) => {
const parent = tasksById[task.parent_id]
if (!parent) {
return tree.concat(task)
}
parent.children = parent.children || []
parent.children.push(task)
return tree
}, [])
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/444587.html
標籤:javascript 递归
下一篇:鏈接串列可以只是一個類嗎?
