简体   繁体   English

将 ES6 可迭代转换为数组

[英]Convert ES6 Iterable to Array

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.在 python 中,你可以只使用 list() 函数。 Is there an equivalent in ES6? ES6 中是否有等价物?

You can use Array.from or spread syntax (...) .您可以使用Array.from传播语法 (...)

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 ]

Summary:概括:

  • Array.from() function, it takes an iterable as in input and returns an array of the iterable. Array.from()函数,它在输入中接受一个可迭代对象并返回一个可迭代对象数组。
  • 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)) .我们可以通过使用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)

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

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}]
 <Your_Array> = [].concat.apply([], Array.from( <Your_IterableIterator> ));

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):或者使用 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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM