Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

flatten javascript array of objects

I have an array of object with hierarchical structure, something like this:

[
    {name: 'ParentOne', children: [
        {name: 'ParentOneChildOne'},
        {name: 'ParentOneChildTwo', children: [
            {name: 'ParentOneChildTwoGrandChildOne'},
        ]},
    ]}, 
    {name: 'ParentTwo', children: [
        {name: 'ParentTwoChildOne', children: [
           {name: 'ParentTwoChildOneGrandChildOne'},
           {name: 'ParentTwoChildOneGrandChildTwo'}
        ]},
        {name: 'ParentTwoChildTwo'}
    ]}
];

I want to flatten it:

[
    {name: 'ParentOne'},
    {name: 'ParentOneChildOne'},
    {name: 'ParentOneChildTwo'},
    {name: 'ParentOneChildTwoGrandChildOne'},
    {name: 'ParentTwo'},
    {name: 'ParentTwoChildOne'},
    {name: 'ParentTwoChildOneGrandChildOne'},
    {name: 'ParentTwoChildOneGrandChildTwo'},
    {name: 'ParentTwoChildTwo'}
]

I have tried _.flatten() and _.flatMap(), but it does not produce what I need. What is the best way to achieve it preferably using lodash.js or underscore.js.

like image 830
koryakinp Avatar asked Dec 02 '22 12:12

koryakinp


2 Answers

No need for underscore/lodash.

const arr = [
    {name: 'ParentOne', children: [
        {name: 'ParentOneChildOne'},
        {name: 'ParentOneChildTwo', children: [
            {name: 'ParentOneChildTwoGrandChildOne'},
        ]},
    ]}, 
    {name: 'ParentTwo', children: [
        {name: 'ParentTwoChildOne', children: [
           {name: 'ParentTwoChildOneGrandChildOne'},
           {name: 'ParentTwoChildOneGrandChildTwo'}
        ]},
        {name: 'ParentTwoChildTwo'}
    ]}
];

function flatten(arr) {
    return arr? arr.reduce((result, item) => [
        ...result,
        { name: item.name },
        ...flatten(item.children)
    ], []) : [];
}

console.log(flatten(arr));
like image 167
ideaboxer Avatar answered Dec 06 '22 12:12

ideaboxer


Recursive functions is the way to go for any depth of iteration.

With some ES2015 and LoDash/Underscore

var arr = [{
  name: 'ParentOne',
  children: [{
    name: 'ParentOneChildOne'
  }, {
    name: 'ParentOneChildTwo',
    children: [{
      name: 'ParentOneChildTwoGrandChildOne'
    }, ]
  }, ]
}, {
  name: 'ParentTwo',
  children: [{
    name: 'ParentTwoChildOne',
    children: [{
      name: 'ParentTwoChildOneGrandChildOne'
    }, {
      name: 'ParentTwoChildOneGrandChildTwo'
    }]
  }, {
    name: 'ParentTwoChildTwo'
  }]
}];

var res = _.reduce(arr, (a, b) => {
  (rec = item => {
    _.each(item, (v, k) => (_.isObject(v) ? rec(v) : a.push(_.zipObject([k], [v]))))
  })(b);
  return a;
}, []);

console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
like image 42
adeneo Avatar answered Dec 06 '22 10:12

adeneo