【问题标题】:Using ES5 array methods with ES6 generators在 ES6 生成器中使用 ES5 数组方法
【发布时间】:2015-04-16 22:35:07
【问题描述】:

在 ES6 生成器中使用新的 ES5 数组函数的正确方法是什么?我是否必须先将可迭代对象显式转换为数组,还是有更好的方法?例如:

function* range(low, high) {
    var i = low;
    while(i < high)
        yield i++;
}

// Sum of numbers in range, doesn't work
console.log(range(0, 10).reduce((x,y) => x + y));

【问题讨论】:

标签: javascript ecmascript-6


【解决方案1】:

使用Array.from构建数组:

console.log(Array.from(range(0, 10)).reduce((x,y) => x + y));

Array.from 从一个可迭代对象创建一个数组。见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from

如果您想在不创建数组的情况下进行 reduce,那么您最终需要执行以下操作:

var sum = 0;
for (e of range(0, 10)) sum += e;

【讨论】:

    【解决方案2】:

    生成器函数返回Iterator 对象。 Iterator API 不包含 mapreduce 等高阶 Array 方法,因此您需要构建一个中间 Array(或使用像 wu.js 这样的库)。

    您可以使用spread operator 从(有限)迭代器简洁地构建一个数组:

    var sum = [...range(0, 10)].reduce((e, i) => e + i)
    

    【讨论】:

    • 它有效,我只是想知道是否有一种内置的方式来处理它,而不必创建中间数组(例如,如果创建的数组非常大)。不过好像没有。
    • 我认为这是不可能的,因为迭代器可以是无限的。您将如何减少无限序列?
    • 是的,好点。 wu.js 看起来像我需要的,所以我会接受这个答案。
    【解决方案3】:

    由于Array.from 目前不能在 Chrome 上运行,我需要另一种方法来将 Iterator 转换为 Array。

    (当然你也可以shim it with a polyfill

    function iterator2Array(iterator) {
        var result = [];
        for (var item in iterator) {
            result.push(item)
        }
        return result;
    }
    

    出于类似的原因,我在 Map 的原型中添加了一个“toArray”,以便我基本上将迭代器转换为数组,以便您可以使用其面向函数的方法;当然,数组的每个项目都是一个 [key, value] 元组(就像在它的 Map.entries() 中一样)

    if (!Map.prototype.toArray) {
        /**
         * Transforms a map into an Array of 'tuples' [[key, value], ...]
         */
        Map.prototype.toArray = function () {
            var result = [];
    
            for (var item of this) {
                result.push(item);
            }
    
            return result;
        }
    }
    
    var m = new Map([[0, 0], ['a', 'A']]);
    m.toArray()
    

    然后您可以将其用作数组 - 不过请记住 [key, value] 方法!

    m.toArray().map(
        function(item, index, array) {
            var key = item[0],
            value = item[1];
            console.log(key + ": " + value);
            return value;
    });
    

    这将返回地图的值(当然不是超级有用!)

    如果您喜欢更标准的循环:

    var i = iterator.entries(),
        result = [],
        value;
    while (value = i.next().value) {
        result.push(value);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-12
      • 2017-10-11
      • 2017-05-16
      • 2014-10-12
      • 2016-08-21
      • 2017-08-27
      相关资源
      最近更新 更多