我试图使用新的地图对象从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,因为它会杀死性能。

其他回答

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

这是过度宽松。

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

你可以使用像https://www.npmjs.com/package/itiriri这样的库,为可迭代对象实现类似数组的方法:

import { query } from 'itiriri';

const map = new Map();
map.set(1, 'Alice');
map.set(2, 'Bob');

const result = query(map)
  .filter([k, v] => v.indexOf('A') >= 0)
  .map([k, v] => `k - ${v.toUpperCase()}`);

for (const r of result) {
  console.log(r); // prints: 1 - ALICE
}

你正在寻找新的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 => {...});

你也可以使用fluent-iterable转换为数组:

const iterable: Iterable<T> = ...;
const arr: T[] = fluent(iterable).toArray();