从对象数组创建树,保留其他键值对
make tree from array of objects, keeping other key value pairs
问题
我有一组平面对象,我想将其变成嵌套树。我试过同时使用递归和归约,但没有达到预期的效果。
具体来说我有数组:
const rawdata = [
{name: "A", parent: "All", value: null},
{name: "C", parent: "A", value: 10},
{name: "D", parent: "A", value: 20},
{name: "E", parent: "A", value: 30},
{name: "B", parent: "All", value: null},
{name: "F", parent: "B", value: 10},
{name: "G", parent: "B", value: 20},
{name: "H", parent: "B", value: 30}
]
想要的结果
我想把它变成:
let result = {name: "All",
children:
[
{name: "A",
children: [
{name: "C", value: 10},
{name: "D", value: 20},
{name: "E", value: 30},
],
value: null,
},
{name: "B",
children: [
{name: "F", value: 10},
{name: "G", value: 20},
{name: "H", value: 30},
],
value: null
}
]
}
我尝试过的:
我已经能够使用递归创建一棵树,其中 All
使用 name
和 parent
值位于最顶层,但我还没有能够弄清楚如何将 values
保留为对象的一部分。
let makeTree = (categories, parent) => {
let node = {}
categories
.filter(c => c.parent === parent)
.forEach(c => node[c.name] =
makeTree(categories, c.name))
return node
}
console.log(JSON.stringify(makeTree(rawdata, "All")), null, 2)
尝试应用此 post 中的代码,但我的情况有点不同。任何帮助表示赞赏!
我也试过使用:Build tree array from flat array in javascript
const nest = (items, id = null, link = 'parent_id') =>
items
.filter(item => item[link] === id)
.map(item => ({ ...item, children: nest(items, item.id) }));
console.log(nest(rawdata, id = 'name', link = 'parent'))
但是也不能让它工作?
我的提议...
const makeTree = arr =>
arr.reduce((r,{name,parent,value,...others},i) =>
{
let refParent = r.pKeys.find(x=>x.name===parent)
if (!refParent) // --> parent==='All'
{
r.res.name = parent
r.res.children = []
refParent = { name: parent, children: r.res.children }
r.pKeys.push( refParent )
}
let newRow = { name, value, ...others }
if (value===null)
{
newRow.children = []
r.pKeys.push( { name, children: newRow.children } )
}
refParent.children.push( newRow )
if (i===r.end) return r.res
return r
}
,{ end:arr.length -1, res:{}, pKeys:[] })
;
// show testing with 3 levels, and additinnal (optionnals) infos
const rawdata =
[ { name: 'A', parent: 'All', value: null }
, { name: 'C', parent: 'A', value: 10 }
, { name: 'D', parent: 'A', value: 20 , info1: 'ty', info2: 'zb' }
, { name: 'E', parent: 'A', value: 30 , info1: 'kg', info2: 'zc' }
, { name: 'B', parent: 'All', value: null }
, { name: 'F', parent: 'B', value: 10 , info1: 'xyz' }
, { name: 'G', parent: 'B', value: null }
, { name: 'H', parent: 'B', value: 30 , info1: 'abc' }
, { name: 'g1', parent: 'G', value: 20 , info1: 'gg1' }
, { name: 'g2', parent: 'G', value: 20 , info1: 'gg2' }
, { name: 'g3', parent: 'G', value: 20 , info1: 'ggg' }
]
let result = makeTree( rawdata )
console.log( result )
.as-console-wrapper { max-height: 100% !important; top: 0; }
我在这个解决方案被分类为重复之前开始编写它。
我只是在我准备好的代码副本的开头,但我发现那里有错误,我删除了它:/
当我想回来进行更正时,问题已重复提交。
还有一些不准确的地方,我想确定我的代码的有效性。我还是个程序员,敲定代码的欲望更强烈
我查看了重复的 link 回复。我只看了一部分 30 个不同的答案
我的解决方案是唯一一个用一个简单而独特的array.reduce()来完成所有事情的解决方案,并且不使用外部变量。
这是我在这里重新激活我的答案的第二个原因。第一个当然是将它呈现给 PO。
问题
我有一组平面对象,我想将其变成嵌套树。我试过同时使用递归和归约,但没有达到预期的效果。
具体来说我有数组:
const rawdata = [
{name: "A", parent: "All", value: null},
{name: "C", parent: "A", value: 10},
{name: "D", parent: "A", value: 20},
{name: "E", parent: "A", value: 30},
{name: "B", parent: "All", value: null},
{name: "F", parent: "B", value: 10},
{name: "G", parent: "B", value: 20},
{name: "H", parent: "B", value: 30}
]
想要的结果
我想把它变成:
let result = {name: "All",
children:
[
{name: "A",
children: [
{name: "C", value: 10},
{name: "D", value: 20},
{name: "E", value: 30},
],
value: null,
},
{name: "B",
children: [
{name: "F", value: 10},
{name: "G", value: 20},
{name: "H", value: 30},
],
value: null
}
]
}
我尝试过的:
我已经能够使用递归创建一棵树,其中 All
使用 name
和 parent
值位于最顶层,但我还没有能够弄清楚如何将 values
保留为对象的一部分。
let makeTree = (categories, parent) => {
let node = {}
categories
.filter(c => c.parent === parent)
.forEach(c => node[c.name] =
makeTree(categories, c.name))
return node
}
console.log(JSON.stringify(makeTree(rawdata, "All")), null, 2)
尝试应用此 post
我也试过使用:Build tree array from flat array in javascript
const nest = (items, id = null, link = 'parent_id') =>
items
.filter(item => item[link] === id)
.map(item => ({ ...item, children: nest(items, item.id) }));
console.log(nest(rawdata, id = 'name', link = 'parent'))
但是也不能让它工作?
我的提议...
const makeTree = arr =>
arr.reduce((r,{name,parent,value,...others},i) =>
{
let refParent = r.pKeys.find(x=>x.name===parent)
if (!refParent) // --> parent==='All'
{
r.res.name = parent
r.res.children = []
refParent = { name: parent, children: r.res.children }
r.pKeys.push( refParent )
}
let newRow = { name, value, ...others }
if (value===null)
{
newRow.children = []
r.pKeys.push( { name, children: newRow.children } )
}
refParent.children.push( newRow )
if (i===r.end) return r.res
return r
}
,{ end:arr.length -1, res:{}, pKeys:[] })
;
// show testing with 3 levels, and additinnal (optionnals) infos
const rawdata =
[ { name: 'A', parent: 'All', value: null }
, { name: 'C', parent: 'A', value: 10 }
, { name: 'D', parent: 'A', value: 20 , info1: 'ty', info2: 'zb' }
, { name: 'E', parent: 'A', value: 30 , info1: 'kg', info2: 'zc' }
, { name: 'B', parent: 'All', value: null }
, { name: 'F', parent: 'B', value: 10 , info1: 'xyz' }
, { name: 'G', parent: 'B', value: null }
, { name: 'H', parent: 'B', value: 30 , info1: 'abc' }
, { name: 'g1', parent: 'G', value: 20 , info1: 'gg1' }
, { name: 'g2', parent: 'G', value: 20 , info1: 'gg2' }
, { name: 'g3', parent: 'G', value: 20 , info1: 'ggg' }
]
let result = makeTree( rawdata )
console.log( result )
.as-console-wrapper { max-height: 100% !important; top: 0; }
我在这个解决方案被分类为重复之前开始编写它。 我只是在我准备好的代码副本的开头,但我发现那里有错误,我删除了它:/ 当我想回来进行更正时,问题已重复提交。
还有一些不准确的地方,我想确定我的代码的有效性。我还是个程序员,敲定代码的欲望更强烈
我查看了重复的 link 回复。我只看了一部分 30 个不同的答案
我的解决方案是唯一一个用一个简单而独特的array.reduce()来完成所有事情的解决方案,并且不使用外部变量。
这是我在这里重新激活我的答案的第二个原因。第一个当然是将它呈现给 PO。