Перетворити ES6 Iterable на Array


101

Скажімо, у вас є схожий на масив Javascript ES6 Iterable, який ви заздалегідь знаєте, буде обмежений, який найкращий спосіб перетворити його на масив Javascript?

Причиною цього є те, що багато бібліотек js, такі як підкреслення та лодаш, підтримують лише масиви, тому, якщо ви хочете використовувати будь-яку їхню функцію в Iterable, її спочатку потрібно перетворити на масив.

У python ви можете просто використовувати функцію list (). Чи існує еквівалент у ES6?


26
Array.from(iterable), див. ECMA-262 ed 6 draft .
RobG

Відповіді:


157

Ви можете використовувати Array.from або оператор поширення .

Приклад:

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 ]


2
Майже те саме стосується структури let m = new Map()даних ES6 : щоб отримати лише значення Array.fromоператора Map, використовуйте або розповсюджуйте оператор m.values(), те саме для m.keys(). В іншому випадку, ви отримаєте масив масивів: [[key, value], [key, value]].
Нік Сумейко

17

Короткий зміст:

  • Array.from() функція, вона приймає ітерабельний, як у введення, і повертає масив ітерабельного.
  • Оператор розповсюдження: ...у поєднанні з літералом масиву.

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

Застереження при копіюванні масивів:

Зверніть увагу на те, що за допомогою цих методів вище, лише коли створюється неглибока копія, ми хочемо скопіювати масив. Приклад прояснить потенційну проблему:

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

let newArr = [ ...arr ];

console.log(newArr);

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

console.log(newArr);

Тут через вкладений масив посилання копіюється і новий масив не створюється. Тому, якщо ми мутуємо вкладений масив старого масиву, ця зміна буде відображена в новому масиві (оскільки вони посилаються на один і той же масив, посилання було скопійовано).

Рішення для застереження:

Ми можемо вирішити проблему неглибоких копій, створивши глибокий клон масиву за допомогою JSON.parse(JSON.stringify(array)). Наприклад:

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)


12

Ви можете використовувати метод Array.from , який додається в ES6, але підтримує лише масиви та ітерабельні об'єкти, такі як Maps and Sets (також ES6). Для звичайних об'єктів, ви можете використовувати Underscore в ToArray метод або метод ToArray lodash, так як обидві бібліотеки на насправді мають велику підтримку об'єктів, а не тільки масиви. Якщо ви вже використовуєте підкреслення або лодаш, то, на щастя, вони можуть вирішити проблему за вас, поряд з додаванням різних функціональних концепцій, таких як карта та зменшення для ваших об’єктів.


3

Для Карт перевірено наступний підхід:

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}]

Не те, про що просили - див. Array.з дороги
Жоау Антунес


-4

Ви також можете зробити:

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

Або "важким шляхом" за допомогою функції генератора ES5 + ( скрипка працює в поточному 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);
}

Обидва ці підходи, безумовно, не рекомендуються і є лише підтвердженням концепції.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.