我试图使用新的地图对象从Javascript EC6,因为它已经支持在最新的Firefox和Chrome版本。

但我发现它在“函数式”编程中非常有限,因为它缺乏经典的映射、过滤器等方法,这些方法可以很好地处理[key, value]对。它有一个forEach,但不返回回调结果。

如果我可以将它的map.entries()从一个MapIterator转换成一个简单的数组,那么我就可以使用标准的.map, .filter而不需要额外的hack。

是否有一个“好”的方法将Javascript迭代器转换为数组? 在python中,这就像执行list(iterator)…但是数组(m.entries())返回一个以迭代器为第一个元素的数组!!

EDIT

我忘记指定我正在寻找一个答案,无论地图工作,这意味着至少Chrome和Firefox(数组.from不工作在Chrome)。

PS.

我知道有很棒的wu.js,但它对traceur的依赖让我很反感……


当前回答

[…map.entries()]或Array.from(map.entries())

这是过度宽松。

总之,迭代器缺少reduce、filter和类似的方法。您必须自己编写它们,因为这比将Map转换为数组再转换回来的性能更好。但是不要做跳跃Map -> Array -> Map -> Array -> Map -> Array,因为它会杀死性能。

其他回答

你正在寻找新的array .from函数,它将任意可迭代对象转换为数组实例:

var arr = Array.from(map.entries());

现在支持Edge, FF, Chrome和Node 4+。

当然,直接在迭代器接口上定义map、filter和类似的方法可能是值得的,这样就可以避免分配数组。你可能还想使用生成器函数而不是高阶函数:

function* map(iterable) {
    var i = 0;
    for (var item of iterable)
        yield yourTransformation(item, i++);
}
function* filter(iterable) {
    var i = 0;
    for (var item of iterable)
        if (yourPredicate(item, i++))
             yield item;
}

2019年的一个小更新:

现在array. from似乎是普遍可用的,而且,它接受第二个参数mapFn,这阻止了它创建一个中间数组。基本上是这样的:

Array.from(myMap.entries(), entry => {...});

使用iter-ops库,你可以直接在map或任何可迭代对象上使用filter和map操作,而不需要将其转换为数组:

import {filter, map, pipe} from 'iter-ops';

const m = new Map<number, number>();

m.set(0, 12);
m.set(1, 34);

const r = pipe(
    m,
    filter(([key, value]) => {
        // return the filter flag as required
    }),
    map(([key, value]) => {
        // return the re-mapped value as required
    })
);

console.log([...r]); //=> print all resulting values

[…map.entries()]或Array.from(map.entries())

这是过度宽松。

总之,迭代器缺少reduce、filter和类似的方法。您必须自己编写它们,因为这比将Map转换为数组再转换回来的性能更好。但是不要做跳跃Map -> Array -> Map -> Array -> Map -> Array,因为它会杀死性能。

你可以得到数组的数组(键和值):

[...this.state.selected.entries()]
/**
*(2) [Array(2), Array(2)]
*0: (2) [2, true]
*1: (2) [3, true]
*length: 2
*/

然后,你可以很容易地从内部获取值,比如map迭代器的键。

[...this.state.selected[asd].entries()].map(e=>e[0])
//(2) [2, 3]