0

I have this;

let subs = [];
 for ( const item of items ) { // array
        for ( const sub of item ) { // array
            subs.push( sub );
        }
    }

and want the same result with this (version 2):

 const arr = Object.values(items).map(item => 
         item.map(sub => sub)
    );

However, in version 2, I get for each "item" a array of "subs" instead of one array holding all "subs" (like in version 1). I need something like "flatMap". Or how can I do that?

nimo23
  • 5,170
  • 10
  • 46
  • 75

2 Answers2

2

Yep, flatMap is rather trivial in ES6

let flatMap = (a, fn) => [].concat(...a.map(fn));

example:

let flatMap = (a, fn) => [].concat(...a.map(fn));

items = [[1,2], [3,4], [5,6]]

console.log(flatMap(items, x=>x))
georg
  • 211,518
  • 52
  • 313
  • 390
  • Thanks, it works. Do you know, which performs faster (version 1 or 2)? I think, "for..of".. – nimo23 Jan 27 '18 at 13:11
  • No idea, but I doubt there will be a noticeable difference unless you have thousands of items. – georg Jan 27 '18 at 13:13
1

A simple solution using reduce would be

items.reduce ((flat, item) => flat.concat (item), [])

var items = [[1,2,3],[4,5,6]]
var flat = items.reduce ((flat, item) => flat.concat (item), []);
console.log (flat)

A recursive version is almost as simple:

var reducer = (flat, item) => Array.isArray (item)?item.reduce(reducer,flat):flat.concat (item);
var items = [[1,2,3,[7,8,9]],[4,5,6]]

console.log (items.reduce(reducer, []))
Moritz Roessler
  • 8,542
  • 26
  • 51