admin管理员组

文章数量:1403187

I am trying to implement a user hierarchy using the js library orgChart. by getHierarchy() method in the library is outputting a object like the following.

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. ex: //["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. Is there much elegant and effective way to do it with single reduce function?

Thank you in advance.

I am trying to implement a user hierarchy using the js library orgChart. by getHierarchy() method in the library is outputting a object like the following.

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. ex: //["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. Is there much elegant and effective way to do it with single reduce function?

Thank you in advance.

Share Improve this question edited Mar 12, 2021 at 18:20 Nina Scholz 387k26 gold badges364 silver badges414 bronze badges asked Mar 8, 2019 at 13:46 Sankha KarunasekaraSankha Karunasekara 1,72619 silver badges22 bronze badges 3
  • 1 Possible duplicate of How to flatten nested array of object using es6 – Mosè Raguzzini Commented Mar 8, 2019 at 13:47
  • The result will be like this ["1", "2", "3", "4", "5", "6", "7", "10", "12"] ? – brk Commented Mar 8, 2019 at 13:47
  • @brk yep that is what I want. thanks. – Sankha Karunasekara Commented Mar 8, 2019 at 13:57
Add a ment  | 

3 Answers 3

Reset to default 6

You could flat the children by taking a mapping with 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:

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. 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

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)

本文标签: