将ES6可迭代转换为数组


100

假设您有一个类似数组的Javascript ES6 Iterable,您事先知道它的长度是有限的,那么将其转换为Javascript数组的最佳方法是什么?

这样做的原因是,许多下划线和lodash之类的js库仅支持Arrays,因此,如果您希望在Iterable上使用其任何功能,则必须首先将其转换为Array。

在python中,您可以只使用list()函数。ES6中是否有等效功能?


26
Array.from(iterable),请参阅ECMA-262第6版草案
RobG 2014年

Answers:


155

您可以使用Array.fromspread操作符

例:

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
ES6let m = new Map()数据结构几乎相同:要获取Map的值,请使用Array.from或上的散布运算符m.values(),与相同m.keys()。否则,您将获得一个数组数组:[[key, value], [key, value]]
Nik Sumeiko

16

概要:

  • Array.from() 函数,它接受输入中的iterable并返回iterable的数组。
  • 传播运算符:...与数组文字组合。

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和Sets(也包含在ES6中)。对于常规对象,可以使用Underscore的toArray方法或lodash的toArray方法,因为这两个库实际上都对对象(而不只是数组)提供了很好的支持。如果您已经在使用下划线或破折号,那么幸运的是它们可以为您解决问题,并为您的对象添加各种功能概念,例如map和reduce。


3

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

没问什么-请看Array.from方法
若昂·安图内斯


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

当然,这两种方法都不值得推荐,仅是概念验证。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.