简体   繁体   English

递归得到所有孩子

[英]Recursively get all children

I need to recursively get all children from a nested object. 我需要以递归方式从嵌套对象中获取所有子项。 I already wrote a function that does it (kinda) but I think it can be improved. 我已经编写了一个功能(有点),但我认为它可以改进。

How can I make it shorter and cleaner? 如何让它更短更干净?

I have included the data I'm using for testing as well as the function I wrote that needs improvement. 我已经包含了我用于测试的数据以及我编写的需要改进的函数。

 let data = [{ id: 1, child: { id: 2, child: { id: 3, child: { id: 4, child: null } } } }, { id: 5, child: { id: 6, child: null } } ]; // function for (let cat of data) { cat.children = getCategoryChild(cat); console.log(cat.children) } function getCategoryChild(cat) { let t = []; if (cat.child != null) { t.push(cat.child); let y = getCategoryChild(cat.child); if (y.length > 0) { for (let i of y) { t.push(i) } } } return t; } 

Expected output: 预期产量:

[{id: 1, children: [{id: 2}, {id: 3}, {id: 4}]}, {id: 5, children: [{id: 6}]}]

You could take a recursive approach by checking the actual child property 您可以通过检查实际的child属性来采取递归方法

 function convert(array) { const iter = o => o ? [{ id: o.id }, ...iter(o.child)] : []; return array.map(({ id, child }) => ({ id, children: iter(child) })); } var data = [{ id: 1, child: { id: 2, child: { id: 3, child: { id: 4, child: null } } } }, { id: 5, child: { id: 6, child: null } }]; console.log(convert(data)); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

assuming that each category only ever has one child 假设每个类别只有一个孩子

edited to adhere to the expected result... 编辑以坚持预期的结果......

function iterChildren(cat) {
  let c = cat, children = [];

  while (c.child) {
    children.push({id: c.child.id});
    c = c.child;
  }

  return {id: cat.id, children: children};
}

let newData = data.map(iterChildren);

I re-wrote the function. 我重写了这个函数。
It filters cats, and only returns an object with id and child_id of each. 它过滤child_id ,只返回一个id和每个child_id的对象。

 let output = [], data = [{ id: 1, child: { id: 2, child: { id: 3, child: { id: 4, child: null } } } }, { id: 5, child: { id: 6, child: null } } ]; function getCategoryChild(cat) { var t = [{ id: cat.id, child_id: null /* HERE you can set, what kind of data should be included to output */ }] if (cat.child) { t[0].child_id = cat.child.id t = t.concat(getCategoryChild(cat.child)) } return t } for (x of data) { output=output.concat(getCategoryChild(x)) } console.log(output) 

EDIT: I edited my code assuming that one cat can have more children: 编辑:我编辑了我的代码,假设一只猫可以有更多的孩子:

 let output = [], data = [{ id: 1, child: { id: 2, child: { id: 3, child: { id: 4, child: null } } } }, { id: 5, child: { id: 6, child: null } }, { id: 7, child: [ { id: 8, child: { id: 9, child: null } }, { id: 10, child: null }, { id: 11, child: null } ] }, ]; function getCategoryChild(cat) { var t = [{ id: cat.id, child_id: [] /* HERE you can set, what kind of data should be included to output */ }] if (cat.child) { if (!(cat.child instanceof Array)) { cat.child = [cat.child] } for (var x of cat.child) { t[0].child_id.push(x.id) t = t.concat(getCategoryChild(x)) } } return t } for (x of data) { output = output.concat(getCategoryChild(x)) } console.log(output) 

data.map(({id,child:c})=>({id,children:[...{*0(){for(;c&&({id}=c);c=c.child)yield{id}}}[0]()]}))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM