简体   繁体   English

在ES6生成器中使用ES5数组方法

[英]Using ES5 array methods with ES6 generators

What's the correct way of using the new ES5 array functions with ES6 generators? 在ES6生成器中使用新ES5阵列功能的正确方法是什么? Do I have to explicitly convert the iterable into an array first, or is there a better way? 我是否必须先将iterable显式转换为数组,还是有更好的方法? For example: 例如:

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

Generator functions return Iterator objects. 生成器函数返回Iterator对象。 The Iterator API does not include higher order Array methods such as map , reduce etc, so you need to build an intermediate Array (or use a library like wu.js ). Iterator API不包括高阶数组方法,如mapreduce等,因此您需要构建一个中间数组(或使用类似wu.js的库)。

You can use the spread operator to concisely build an Array from a (finite) iterator: 您可以使用spread运算符从(有限)迭代器中简明地构建一个数组:

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

Build the array using Array.from : 使用Array.from构建数组:

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

Array.from creates an array from an iterable. Array.from从iterable创建一个数组。 See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from . 请参阅https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from

If you want to do the reduce without creating the array, then you'll end up needing to do something like: 如果你想在不创建数组的情况下进行reduce,那么你最终需要做类似的事情:

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

Since Array.from does not work on Chrome at the current time, I needed another way to convert an Iterator into an Array. 由于Array.from目前在Chrome上不起作用,我需要另一种方法将Iterator转换为数组。

(though of course you can shim it with a polyfill ) (当然你可以用polyfill填充它

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

For similar reasons I add a "toArray" to the prototype of a Map so that I basically convert an iterator into an Array so that you can use its functional-oriented methods; 出于类似的原因,我在Map的原型中添加了一个“toArray”,这样我基本上就可以将迭代器转换为一个Array,这样就可以使用它的面向功能的方法了。 of course each item of the array will be a [key, value] tuple (exactly like in its Map.entries() ) 当然,数组的每个项目都是[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()

Then you can use it as an array - remember the [key, value] approach though! 然后你可以将它用作数组 - 记住[key,value]方法!

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

This will return the values of the map (ok not superuseful of course!) 这将返回地图的值(当然不是超级有用!)

If you prefer a more standar looking loop: 如果您更喜欢更环保的循环:

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

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

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