-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
  • 6,256
  • 6
  • 44
  • 79
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
  • 376,160
  • 25
  • 347
  • 392
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
  • 118,580
  • 15
  • 151
  • 176
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
  • 12
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,606
  • 14
  • 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
  • 25,060
  • 6
  • 56
  • 76
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,035
  • 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
  • 118,978
  • 58
  • 307
  • 400
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,953
  • 3
  • 18
  • 24