Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/388.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在树数据结构中聚合包含对象数组的属性_Javascript_Recursion_Tree - Fatal编程技术网

Javascript 在树数据结构中聚合包含对象数组的属性

Javascript 在树数据结构中聚合包含对象数组的属性,javascript,recursion,tree,Javascript,Recursion,Tree,我有一个如下的树结构(没有深度限制,一般不超过6个子级别)。每个节点都有一个workItems属性,即workItem对象的数组 我想在每个节点上聚合工作项,这样一个节点就包含了它自己的工作项和它的所有后代的工作项 以下结构示例中,节点id11将具有以下工作项: [{ id: 'wi2' }, { id: 'wi3' }, { id: 'wi4' }, { id: 'wi5' }] // aggregated from node `111` 节点1将绝对

我有一个如下的树结构(没有深度限制,一般不超过6个子级别)。每个节点都有一个
workItems
属性,即
workItem
对象的数组

我想在每个节点上聚合
工作项
,这样一个节点就包含了它自己的工作项和它的所有后代的工作项

以下结构示例中,节点id
11
将具有以下工作项:

    [{ id: 'wi2' },
     { id: 'wi3' },
     { id: 'wi4' }, 
     { id: 'wi5' }] // aggregated from node `111`
节点
1
将绝对拥有树的所有工作项

javascript

const traverse = (tree) => {
    const stack = [ tree ]

    while (stack.length) {
        const curr = stack.pop()

        // do something here, I guess

        stack.push(...curr.children)
    }
}
树结构

    {
        id: '1',
        title: '1',
        workItems: [
            { id: 'wi1' }
        ],
        children: [
            {
                id: '11',
                title: '11',
                workItems: [
                    { id: 'wi2' },
                    { id: 'wi3' },
                    { id: 'wi4' }           
                ],
                children: [
                    {
                        id: '111',
                        title: '111',
                        workItems: [
                            { id: 'wi5' },
                        ],
                        children: []
                    }
                ]
            },
            {
                id: '12',
                title: '12',
                workItems: [
                    { id: 'wi6' }                           
                ],
                children: [
                    {
                        id: '121',
                        title: '121',
                        workItems: [
                            { id: 'wi7' },
                            { id: 'wi8' }
                        ],
                        children: []
                    }
                ]
            }
        ]
    }



您可以进行深度优先搜索,并将
workItmes
的父数组交给pusihng嵌套项

const
getWorkItems=({workItems,children=[]})=>
(workItems.push(…children.flatMap(getWorkItems)),workItems);
变量树={id:'1',title:'1',工作项:[{id:'wi1'}],子项:[{id:'11',title:'11',工作项:[{id:'wi2'},{id:'wi3'},{id:'wi4'}],子项:[{id:'111',title:'111',工作项:[{id:'wi5'}],子项:[},{id:'12',工作项:[{id:'wi6'}],子项:[id:'121',title:'121',工作项:[{id:'wi7'},{id:'wi8'}],子项:[]}]};
getWorkItems(树);
console.log(树);

.as console wrapper{max height:100%!important;top:0;}
您可以进行深度优先搜索,并移交
工作项的父数组
,以显示嵌套项

const
getWorkItems=({workItems,children=[]})=>
(workItems.push(…children.flatMap(getWorkItems)),workItems);
变量树={id:'1',title:'1',工作项:[{id:'wi1'}],子项:[{id:'11',title:'11',工作项:[{id:'wi2'},{id:'wi3'},{id:'wi4'}],子项:[{id:'111',title:'111',工作项:[{id:'wi5'}],子项:[},{id:'12',工作项:[{id:'wi6'}],子项:[id:'121',title:'121',工作项:[{id:'wi7'},{id:'wi8'}],子项:[]}]};
getWorkItems(树);
console.log(树);

.as console wrapper{max height:100%!important;top:0;}
这是一个创建新树而不是修改当前树的版本。(我非常喜欢不可变数据。)请注意,
工作项仍然通过引用共享,包括在单个树内以及原始树和派生树之间

const addalldecents=(
{workItems,children=[],…rest},{,},
kids=children.map(addAllDecents)
) => ({
休息
workItems:[…workItems,…kids.flatMap(child=>child.workItems)],
孩子们:孩子们,
})
const tree={id:“1”,title:“1”,工作项:[{id:“wi1”},子项:[{id:“11”,title:“11”,工作项:[{id:“wi2”},{id:“wi3”},{id:“wi4”},子项:[{id:“111”,title:“111”,工作项:[{id:“wi5”},子项:[},{id:“12”,工作项:[{id:“wi6”},子项:[id:“121”,title:“wi8”{}],子项:[]}]};
log('New tree:',addAllDecents(tree))
console.log('原始树:',树)

.as console wrapper{max height:100%!important;top:0;}
这是一个创建新树而不是修改当前树的版本。(我非常喜欢不可变数据。)请注意,
工作项仍然通过引用共享,包括在单个树内以及原始树和派生树之间

const addalldecents=(
{workItems,children=[],…rest},{,},
kids=children.map(addAllDecents)
) => ({
休息
workItems:[…workItems,…kids.flatMap(child=>child.workItems)],
孩子们:孩子们,
})
const tree={id:“1”,title:“1”,工作项:[{id:“wi1”},子项:[{id:“11”,title:“11”,工作项:[{id:“wi2”},{id:“wi3”},{id:“wi4”},子项:[{id:“111”,title:“111”,工作项:[{id:“wi5”},子项:[},{id:“12”,工作项:[{id:“wi6”},子项:[id:“121”,title:“wi8”{}],子项:[]}]};
log('New tree:',addAllDecents(tree))
console.log('原始树:',树)

。作为控制台包装器{max height:100%!important;top:0;}
树是对象(如示例)还是数组?有一种方法可以在不使用真正递归的情况下实现这一点。我将很快发布一个演示。为什么不使用递归?@NinaScholz,没有理由。我不太擅长这一点。研究您的解决方案很有启发性。树是对象吗(如示例所示)或者一个数组?有一种方法不需要真正的递归就可以实现。我很快会发布一个演示。为什么不使用递归?@NinaScholz,没有理由。我不是很擅长这一切。但是研究你的解决方案很有启发性。Scott,由于某些原因,我无法让它工作,我认为Nina的答案更容易一些。再次感谢你花时间讨论answer.Nina的答案当然更简单,而且和Nina的答案一样,非常好。我的设计是为了满足一个额外的限制:我不喜欢变异数据,而是创建新的结构。我不知道为什么它对你不起作用,但可能是你在一个没有
flatMap
的环境中工作。如果是这样,我补充说斯科特,由于某种原因,我无法让它工作,我认为尼娜的答案更容易一些。再次感谢你花时间回答。尼娜的答案当然更容易,而且和尼娜的答案一样,非常好。我的答案是为了满足一个额外的限制:我更喜欢不改变数据,而不是创建数据新结构。我不知道为什么它不适合您,但可能是您在没有
flatMap
的环境中工作。如果是这样,我又添加了一个版本来避免这种情况。如果数据结构是平面的,您的方法是什么:一个
数组