【问题标题】:Convert ES6 Iterable to Array将 ES6 可迭代对象转换为数组
【发布时间】:2015-02-21 03:27:24
【问题描述】:

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

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

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

【问题讨论】:

标签: javascript arrays ecmascript-6 iterable babeljs


【解决方案1】:

您可以使用Array.fromspread syntax (...)

例子:

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 ]

【讨论】:

  • 几乎同样适用于 ES6 let m = new Map() 数据结构:要仅获取 Map 的值,请使用 Array.fromm.values() 上的扩展运算符,m.keys() 相同。否则,你会得到一个数组数组:[[key, value], [key, value]]
【解决方案2】:

总结:

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      针对地图测试了以下方法:

      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 方式
      【解决方案5】:
       <Your_Array> = [].concat.apply([], Array.from( <Your_IterableIterator> ));
      

      【讨论】:

      • 将一个空数组连接到Array.from 的结果是完全没有意义的。
      【解决方案6】:

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

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

      【讨论】:

        猜你喜欢
        • 2021-04-21
        • 2019-05-07
        • 2011-09-20
        • 2017-12-30
        • 2012-05-07
        • 2011-10-03
        • 2020-04-11
        • 1970-01-01
        • 2014-10-02
        相关资源
        最近更新 更多