简体   繁体   English

使用带有递归的reduce函数从多级树生成一个平面的id数组?

[英]Generate a flat array of ids from a multilevel tree using reduce function with recursion?

I am trying to implement a user hierarchy using the js library orgChart .我正在尝试使用 js 库orgChart实现用户层次结构。 by getHierarchy() method in the library is outputting a object like the following.通过库中的getHierarchy()方法输出如下对象。

var datascource = {
            "id": "1",
            "children": [{
                "id": "2"
            }, {
                "id": "3",
                "children": [{
                    "id": "4"
                }, {
                    "id": "5",
                    "children": [{
                        "id": "6"
                    }, {
                        "id": "7"
                    }]
                }]
            }, {
                "id": "10"
            }, {
                "id": "12"
            }]
        };

I want to generate flat array from ids in the tree.我想从树中的 id 生成平面数组。 ex: //["1", "2", "3", "4", "5", "6", "7", "10", "12"]例如: //["1", "2", "3", "4", "5", "6", "7", "10", "12"]

I came up with,我想出了,

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"]

I have try to do it with single reduce function but I end up writing two functions both of them are recursive.我尝试使用单个 reduce 函数来完成它,但最终我编写了两个函数,它们都是递归的。 Is there much elegant and effective way to do it with single reduce function?有没有很多优雅有效的方法可以用单一的reduce函数来做到这一点?

Thank you in advance.先感谢您。

You could flat the children by taking a mapping with concat .您可以通过使用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));

Same with a reduce function与减少功能相同

 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));

Use a recursion with Array.flatMap() and spread to get the id and children's ids, and flatten to a single array: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);

You can create a simple recursive function & use for..in to iterate it.您可以创建一个简单的recursive函数并使用for..in对其进行迭代。 If the key is id then push the value of it to an array, else if the value of the key is an array , for example the value of children key is an array , then call the same recursive function inside a for loop and pass each object如果键是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)

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

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