Convert ES6 Iterable to Array

JavascriptArraysEcmascript 6IterableBabeljs

Javascript Problem Overview


Say you have an array-like Javascript ES6 Iterable that you know in advance will be finite in length, what's the best way to convert that to a Javascript Array?

The reason for doing so is that many js libraries such as underscore and lodash only support Arrays, so if you wish to use any of their functions on an Iterable, it must first be converted to an Array.

In python you can just use the list() function. Is there an equivalent in ES6?

Javascript Solutions


Solution 1 - Javascript

You can use Array.from or spread syntax (...).

Example:

const x = new Set([ 1, 2, 3, 4 ]);

const y = Array.from(x);
console.log(y); // = [ 1, 2, 3, 4 ]

const z = [ ...x ];
console.log(z); // = [ 1, 2, 3, 4 ]

Solution 2 - Javascript

Summary:

  • Array.from() function, it takes an iterable as in input and returns an array of the iterable.
  • Spread syntax: ... in combination with an array literal.

const map = new Map([[ 1, 'one' ],[ 2, 'two' ]]);

const newArr1  = [ ...map  ];  // create an Array literal and use the spread syntax on it
const newArr2 = Array.from( map );  // 

console.log(newArr1, newArr2); 

Caveat when copying arrays:

Be cognizant of the fact that via these methods above only a shallow copy is created when we want to copy an array. An example will clarify the potential issue:

let arr = [1, 2, ['a', 'b']];

let newArr = [ ...arr ];

console.log(newArr);

arr[2][0] = 'change';

console.log(newArr);

Here because of the nested array the reference is copied and no new array is created. Therefore if we mutate the inner array of the old array, this change will be reflected in the new array (because they refer to the same array, the reference was copied).

Solution for caveat:

We can resolve the issue of having shallow copies by creating a deep clone of the array using JSON.parse(JSON.stringify(array)). For example:

let arr = [1, 2, ['a', 'b']]

let newArr = Array.from(arr);

let deepCloneArr = JSON.parse(JSON.stringify(arr));

arr[2][0] = 'change';

console.log(newArr, deepCloneArr)

Solution 3 - Javascript

You can use the Array.from method, which is being added in ES6, but only supports arrays and iterable objects like Maps and Sets (also coming in ES6). For regular objects, you can use Underscore's toArray method or lodash's toArray method, since both libraries actually have great support for objects, not just arrays. If you are already using underscore or lodash, then luckily they can handle the problem for you, alongside adding various functional concepts like map and reduce for your objects.

Solution 4 - Javascript

The following approach is tested for Maps:

const MyMap = new Map([  ['a', 1],
  ['b', 2],
  ['c', 3]
]);

const MyArray = [...MyMap].map(item => {
  return {[item[0]]: item[1]}
});

console.info( MyArray ); //[{"a", 1}, {"b", 2}, {"c": 3}]

Solution 5 - Javascript

 <Your_Array> = [].concat.apply([], Array.from( <Your_IterableIterator> ));

Solution 6 - Javascript

You could also do the following, but both approaches are certainly not recommendable (merely a proof-of-concept for completeness):

let arr = [];
for (let elem of gen(...)){
    arr.push(elem);
}

Or "the hard way" using ES5 + generator function (Fiddle works in current Firefox):

var squares = function* (n) {
  for (var i = 0; i < n; i++) {
    yield i * i;
  }
};

var arr = [];
var gen = squares(10);
var g;
while (true) {
  g = gen.next();
  if (g.done) {
    break;
  }
  arr.push(g.value);
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMichael BylstraView Question on Stackoverflow
Solution 1 - JavascriptXåpplI'-I0llwlg'I -View Answer on Stackoverflow
Solution 2 - JavascriptWillem van der VeenView Answer on Stackoverflow
Solution 3 - JavascriptColin HartwigView Answer on Stackoverflow
Solution 4 - JavascriptRomanView Answer on Stackoverflow
Solution 5 - JavascriptDionis OrosView Answer on Stackoverflow
Solution 6 - JavascriptCodeManXView Answer on Stackoverflow