Konwertuj iterowalne ES6 na Array

102

Załóżmy, że masz tablicę Iterable Javascript ES6, o której wiesz z góry, że będzie miała skończoną długość. Jaki jest najlepszy sposób, aby przekonwertować to na tablicę JavaScript?

Powodem tego jest fakt, że wiele bibliotek js, takich jak podkreślenia i lodash, obsługuje tylko tablice, więc jeśli chcesz użyć którejkolwiek z ich funkcji na tablicy iterowalnej, musisz najpierw przekonwertować ją na tablicę.

W Pythonie możesz po prostu użyć funkcji list (). Czy w ES6 jest odpowiednik?

Michael Bylstra
źródło
27
Array.from(iterable)patrz projekt ECMA-262 ed 6 .
RobG,

Odpowiedzi:

158

Możesz użyć Array.from lub operatora spreadu .

Przykład:

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

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

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

XåpplI'-I0llwlg'I -
źródło
2
Prawie to samo dotyczy let m = new Map()struktury danych ES6 : aby uzyskać tylko wartości mapy, użyj Array.fromoperatora lub rozrzutu m.values(), to samo dotyczy m.keys(). W przeciwnym razie, dostaniesz tablicę tablic: [[key, value], [key, value]].
Nik Sumeiko
17

Podsumowanie:

  • Array.from() funkcja, przyjmuje iterowalną wartość jak w input i zwraca tablicę iterowalnych.
  • Operator spreadu: ...w połączeniu z literałem tablicowym.

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); 

Ostrzeżenie podczas kopiowania tablic:

Należy pamiętać o tym, że za pomocą powyższych metod tworzona jest tylko płytka kopia, gdy chcemy skopiować tablicę. Przykład wyjaśni potencjalny problem:

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

let newArr = [ ...arr ];

console.log(newArr);

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

console.log(newArr);

W tym przypadku z powodu zagnieżdżonej tablicy odniesienie jest kopiowane i nie jest tworzona nowa tablica. Dlatego jeśli zmienimy zagnieżdżoną tablicę starej tablicy, ta zmiana zostanie odzwierciedlona w nowej tablicy (ponieważ odwołują się do tej samej tablicy, odwołanie zostało skopiowane).

Rozwiązanie do zastrzeżenia:

Możemy rozwiązać problem posiadania płytkich kopii, tworząc głęboki klon tablicy za pomocą JSON.parse(JSON.stringify(array)). Na przykład:

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)

Willem van der Veen
źródło
12

Możesz użyć metody Array.from , która jest dodawana w ES6, ale obsługuje tylko tablice i obiekty iterowalne, takie jak mapy i zestawy (również dostępne w ES6). W przypadku zwykłych obiektów można użyć metody Underscore toArray lub metody lodash toArray, ponieważ obie biblioteki mają świetne wsparcie dla obiektów, a nie tylko tablic. Jeśli używasz już podkreślenia lub lodash, na szczęście mogą one rozwiązać problem za Ciebie, a także dodać różne koncepcje funkcjonalne, takie jak mapa i redukcja dla twoich obiektów.

Colin Hartwig
źródło
3

Poniższe podejście jest testowane w przypadku Map:

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}]
rzymski
źródło
Nie to, o co pytano - zobacz Array. From way
João Antunes
0
 <<Your_Array>> = [].concat.apply([], Array.from( <<Your_IterableIterator>> ));
Dionis Oros
źródło
-3

Możesz też:

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

Lub „na uboczu” przy użyciu funkcji generatora ES5 + ( Fiddle działa w aktualnej przeglądarce 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);
}

Oba te podejścia z pewnością nie są jednak godne polecenia i stanowią jedynie dowód słuszności koncepcji.

CodeManX
źródło