-1

I have the following structure:

const array = [
  [
    [
      [
        [
          {
            'name':'John'
          }
        ],
        {
          'name':'Mary'
        }
      ],
      {
        'name':'Cris'
      }
    ],
    {
      'name':'Deen'
    }
  ],
  {
    'name':'Bob'
  }
]

And I'd like to get the following structure as a result:

const expect = [
  {
    'name':'John'
  },
  {
    'name':'Mary'
  },
  {
    'name':'Cris'
  },
  {
    'name':'Deen'
  },
  {
    'name':'Bob'
  },
]

How do I make such conversion with lodash or another library?

polkovnikov.ph
  • 5,806
  • 4
  • 42
  • 74
aloebys
  • 123
  • 2
  • 10

8 Answers8

1

You could use _.flattenDeep from lodash:

Recursively flattens array.

const array = [[[[[{ name: 'John' }], { name: 'Mary' }], { name: 'Cris' }], { name: 'Deen' }], { name: 'Bob' }];
    
console.log(_.flattenDeep(array));
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
Nina Scholz
  • 351,820
  • 24
  • 303
  • 358
1

You can create recursive function using reduce() to return desired result.

const array = [[[[[{"name":"John"}],{"name":"Mary"}],{"name":"Cris"}],{"name":"Deen"}],{"name":"Bob"}]

function flatten(arr) {
  return arr.reduce(function(r, e) {
     return r = r.concat(Array.isArray(e) ? flatten(e) : e), r
  }, [])
}

console.log(flatten(array))
Nenad Vracar
  • 111,264
  • 15
  • 131
  • 153
1

You can use this npm package npm underscore and this is a simple example: var _ = require('underscore-node'); var extractedArray = _.flatten(deepArray)

Ninja
  • 486
  • 4
  • 10
0
function flattenArray(array, result) {
    result = result || [];
    for (var i = 0; i < array.length; i++) {
        if (Array.isArray(array[i])) {
            flattenArray(array[i], result);
        } else {
            result.push(array[i]);
        }
    }

    return result;
}

I wrote this some time back. Follows a recursive approach and is really fast as well.

JSPerf: https://jsperf.com/flatten-array-r1

gauravmuk
  • 1,540
  • 13
  • 20
0

By pure ES6 and a Haskellesque pattern matching implemented by destructuring, you may simply do as follows;

function flat([a,...b]){
  return (Array.isArray(a) ? flat(a) : [a]).concat(b.length ? flat(b) : []);
}

var arr = [[[[[{"name":"John"}],{"name":"Mary"}],{"name":"Cris"}],{"name":"Deen"}],{"name":"Bob"}],
    res = flat(arr);
console.log(res);
Redu
  • 22,595
  • 5
  • 50
  • 67
0

You can do it with closures and a single line of code with ES6. Libraries, when not necessary are a burden. Avoid them where you can.

const flatten = arr => arr.reduce((r, e) => (r = r.concat(Array.isArray(e) ? flatten(e) : e), r), []);

const array = [
  [
    [
      [
        [{
          'name': 'John'
        }],
        {
          'name': 'Mary'
        }
      ],
      {
        'name': 'Cris'
      }
    ],
    {
      'name': 'Deen'
    }
  ],
  {
    'name': 'Bob'
  }
];
console.log(flatten(array))
Rick
  • 1,005
  • 10
  • 18
0

Optimal way without any library and using good-old JS logic:

var arr = [
  [
    [
      [
        [
          {
            'name':'John'
          }
        ],
        {
          'name':'Mary'
        }
      ],
      {
        'name':'Cris'
      }
    ],
    {
      'name':'Deen'
    }
  ],
  {
    'name':'Bob'
  }
];

// convert to string and remove all Array "[" and "]" symbols
var str = JSON.stringify(arr).replace(/\[|]/g,'');
// convert the String back to an Object (Array)
var flatArr = JSON.parse("[" + str + "]");

console.log(flatArr)
Community
  • 1
  • 1
vsync
  • 103,437
  • 51
  • 275
  • 359
0

Consider using object-scan. It's powerful for doing in memory data structure processing (once you wrap your head around it).

Here is how you could solve your example

// const objectScan = require('object-scan');

const find = (input) => objectScan(['**'], {
  reverse: false,
  rtn: 'value',
  filterFn: ({ value }) => typeof value.name === 'string'
})(input);

const array = [[[[[{ name: 'John' }], { name: 'Mary' }], { name: 'Cris' }], { name: 'Deen' }], { name: 'Bob' }];

console.log(find(array));
// => [ { name: 'John' }, { name: 'Mary' }, { name: 'Cris' }, { name: 'Deen' }, { name: 'Bob' } ]
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-scan@13.8.0"></script>

Disclaimer: I'm the author of object-scan

vincent
  • 1,556
  • 1
  • 15
  • 21