Javascript 将 ES6 可迭代转换为数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27612713/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 00:23:42  来源:igfitidea点击:

Convert ES6 Iterable to Array

javascriptarraysecmascript-6iterablebabeljs

提问by Michael Bylstra

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?

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

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.

这样做的原因是很多js库比如underscore和lodash都只支持Arrays,所以如果你想在Iterable上使用它们的任何一个函数,必须先把它转换成一个Array。

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

在 python 中,你可以只使用 list() 函数。ES6 中是否有等价物?

回答by X?pplI'-I0llwlg'I -

You can use Array.fromor the spread operator.

您可以使用Array.from扩展运算符

Example:

例子:

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 ]

回答by Colin Hartwig

You can use the Array.frommethod, 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 toArraymethod 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.

您可以使用ES6 中添加的Array.from方法,但仅支持数组和可迭代对象,如 Maps 和 Sets(也在 ES6 中提供)。对于常规对象,您可以使用Underscore的toArray方法或 lodash 的 toArray 方法,因为这两个库实际上都对对象有很好的支持,而不仅仅是数组。如果您已经在使用下划线或 lodash,那么幸运的是他们可以为您处理问题,同时为您的对象添加各种功能概念,如 map 和 reduce。

回答by Willem van der Veen

Summary:

概括:

  • Array.from()function, it takes an iterable as in input and returns an array of the iterable.
  • Spread operator: ...in combination with an array literal.
  • 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); 

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 clearify 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 nested 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:

我们可以通过使用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)

回答by Roman

The following approach is tested for Maps:

以下方法已针对 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}]

回答by CodeManX

You could also do:

你也可以这样做:

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

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

或者使用 ES5 + 生成器函数的“困难方式”(Fiddle在当前的 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);
}

Both are approaches are certainly not recommendable however and are merely a proof-of-concept.

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