使用带有递归的reduce函数从多级树中生成一个扁平的id数组?
Posted
技术标签:
【中文标题】使用带有递归的reduce函数从多级树中生成一个扁平的id数组?【英文标题】:Generate a flat array of ids from a multilevel tree using reduce function with recursion? 【发布时间】:2019-07-30 13:32:16 【问题描述】:我正在尝试使用 js 库 orgChart 实现用户层次结构。通过库中的getHierarchy()
方法正在输出如下对象。
var datascource =
"id": "1",
"children": [
"id": "2"
,
"id": "3",
"children": [
"id": "4"
,
"id": "5",
"children": [
"id": "6"
,
"id": "7"
]
]
,
"id": "10"
,
"id": "12"
]
;
我想从树中的 id 生成平面数组。
例如://["1", "2", "3", "4", "5", "6", "7", "10", "12"]
我想出了,
function getNestedArraysOfIds(node)
if (node.children == undefined)
return [node.id];
else
return [node.id,...node.children.map(subnode => (subnode.children==undefined) ? subnode.id: getNestedArraysOfIds(subnode))];
function getIds(array)
return array.reduce((acc, subArray) =>
(Array.isArray(subArray)) ? [...acc, ...getIds(subArray)] : [...acc, subArray]);
var idArrays = getNestedArraysOfIds(datascource );
var ids = getIds(idArrays); //["1", "2", "3", "4", "5", "6", "7", "10", "12"]
我尝试使用单个 reduce 函数来实现,但最终我编写了两个函数,它们都是递归的。有没有很多优雅有效的方法可以用单一的 reduce 函数来做到这一点?
提前谢谢你。
【问题讨论】:
How to flatten nested array of object using es6的可能重复 结果会是这样["1", "2", "3", "4", "5", "6", "7", "10", "12"]
?
@brk 是的,这就是我想要的。谢谢。
【参考方案1】:
使用Array.flatMap()
进行递归并传播以获取 id 和孩子的 id,并展平为单个数组:
const getIds = ( id, children ) => children ? [id, ...children.flatMap(getIds)] : id;
const dataSource = "id":"1","children":["id":"2","id":"3","children":["id":"4","id":"5","children":["id":"6","id":"7"]],"id":"10","id":"12"];
const result = getIds(dataSource);
console.log(result);
【讨论】:
【参考方案2】:您可以通过使用concat
进行映射来扁平化孩子。
function getFlat( id, children = [] )
return [id].concat(...children.map(getFlat));
var data = id: "1", children: [ id: "2" , id: "3", children: [ id: "4" , id: "5", children: [ id: "6" , id: "7" ] ] , id: "10" , id: "12" ] ;
console.log(getFlat(data));
与reduce函数相同
function getFlat( id, children = [] )
return children.reduce((r, o) => [...r, ...getFlat(o)], [id]);
var data = id: "1", children: [ id: "2" , id: "3", children: [ id: "4" , id: "5", children: [ id: "6" , id: "7" ] ] , id: "10" , id: "12" ] ;
console.log(getFlat(data));
【讨论】:
【参考方案3】:您可以创建一个简单的recursive
函数并使用for..in
对其进行迭代。如果键是id
,则将它的值压入数组,否则如果键的值是数组,例如children
键的值是数组,则在 for 中调用相同的递归函数循环并传递每个对象
let datascource =
"id": "1",
"children": [
"id": "2"
,
"id": "3",
"children": [
"id": "4"
,
"id": "5",
"children": [
"id": "6"
,
"id": "7"
]
]
,
"id": "10"
,
"id": "12"
]
;
let data = [];
function flatData(obj)
for (let keys in obj)
if (keys === 'id')
data.push(obj[keys])
else if (Array.isArray(obj[keys]))
obj[keys].forEach((item) =>
flatData(item)
)
flatData(datascource)
console.log(data)
【讨论】:
以上是关于使用带有递归的reduce函数从多级树中生成一个扁平的id数组?的主要内容,如果未能解决你的问题,请参考以下文章