132

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

这样做的原因是很多 js 库如 underscore 和 lodash 只支持数组,所以如果你想在 Iterable 上使用它们的任何函数,必须先将其转换为数组。

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

4

6 回答 6

200

您可以使用Array.from传播语法 (...)

例子:

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 ]

于 2015-04-08T12:37:58.527 回答
22

概括:

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

于 2018-08-15T19:25:29.130 回答
13

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

于 2015-01-10T19:03:05.900 回答
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}]
于 2018-10-30T13:40:01.320 回答
1
 <Your_Array> = [].concat.apply([], Array.from( <Your_IterableIterator> ));
于 2020-06-23T06:48:09.930 回答
-3

您也可以执行以下操作,但是这两种方法当然都不推荐(仅仅是完整性的概念验证):

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

或者使用 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);
}
于 2015-08-26T21:35:35.703 回答