是否可以在 ES6 Set 实例上使用数组迭代方法?

Is it possible to use array iteration methods on ES6 Set instances?

我正在使用 ES6 Set 实例,我需要对它们应用一些转换。如果它们是数组,这些转换会很简单。这是一个例子:

let s = new Set;
s.add(1);
s.add(2);
s.add(3);
let n = s.filter(val => val > 1); // TypeError, filter not defined
let n = Array.prototype.filter.call(s, val => val > 1); // []

我希望结果是一个新的 Set 或一个数组。我同样想使用其他数组理解方法,如 filtermapreduce 等。我也希望在 ES6 Map 实例上也有类似的行为。

这可能吗,还是我需要使用 vanilla JS 数组?

您可以使用

获取数组中 s 的值
Array.from(s.values())

Array.from documentation 指出它从类数组或可迭代对象创建一个新的 Array 实例。

Set.values returns 一个新的 Iterator 对象,它包含按插入顺序排列的 Set 对象中每个元素的值。

所以你的代码变成了

let s = new Set;
s.add(1);
s.add(2);
s.add(3);
let n = Array.from(s.values()).filter(val => val > 1)

您不能直接在 SetMap 对象上使用 Array 方法。数组方法需要 .length[n] 索引,这不是 SetMap 的工作方式。

您可以使用 Array.from(s)Set 转换为数组,也可以创建自己的方法直接在 SetMap 上进行操作。如果您要经常这样做并且期望的最终结果是 SetMap,那么最好不要转换为数组,修改,然后再转换回来。另外,将 Map 转换为数组并不是那么简单,因为您同时拥有键和值(可能必须是对象数组)。

例如,您可以像这样为 Set 对象创建自己的 .filter() 方法:

Set.prototype.filter = function(fn) {
    let result = new Set();
    for (let val of this) {
       if (fn(val, this) === true) {
           result.add(val);
       }
    }
    return result;
}

let s = new Set;
s.add(1);
s.add(2);
s.add(3);
let n = s.filter(val => val > 1); 


// log the output

// log output
document.write("Set {" + Array.from(n).join(", ") +"}");

可以为其他 Array 方法创建类似的方法。