为什么我不能用Set对象

时间:2016-05-11 21:11:17

标签: javascript arrays set ecmascript-6

我希望使用ES6的Set从某些字符串中获取唯一字符。 所以我们假设我们有字符串var str = 'abcdeaabc';并从该字符串创建一组字符:

var str = 'abcdeaadbc';
var chars = new Set(str);

现在我们有了一组独特的字符:abcd。 我很惊讶char设置了forEach方法并且没有map方法。

Set是可迭代对象,为什么我们不能使用map函数迭代set?

我尝试以这种方式将chars set和chars.values() SetIterator传递给Array.prototype.map

Array.prototype.map.call(chars, function(element) {...});
Array.prototype.map.call(chars.values(), function(element) {...});

但每次尝试都失败了。

例如,假设我们想要从字符串中获取唯一符号并返回带有前面下划线的数组。例如:['_a', '_b', '_c', '_d']

以下是我的两个解决方案:

// First:
var result = Array.from(chars).map(function(c) {
    return '_' + c;
});

// Second:
var result = [];
chars.forEach(function(c) {
    this.push('_' + c);
}, result);

但是有没有办法用map上下文调用Array.prototype的Set函数?如果不是 - 为什么?

3 个答案:

答案 0 :(得分:5)

Array.prototype.map适用于具有整数索引和length属性的类数组类型。 SetMap是一般可迭代类型,但它们不是类似数组的,因此Array.prototype方法不适用于它们。 e.g。

var s = new Set([1, 2, 3]);
s.length === undefined;
s[0] === undefined

主要方法Array.from有点像你的解决方案,但需要注意的一点是Array.frommapFn作为第二个参数,所以你可以做到

let results = Array.from(chars, c => `_${c}`);

用于将可迭代转换为数组的漂亮的短映射。

答案 1 :(得分:1)

因为即使map足够通用,可以处理任意类似数组的对象,也不是所有可迭代对象都是类似数组的。

map只获取length属性,然后将属性从0迭代到length-1。这不适用于集合,因为它们有size而不是length,并且它们不提供对其元素的随机访问。

如果你真的想使用map,你需要将集合转换为数组,然后将结果转换回集合。

var newSet = new Set(Array.from(set).map(myFunc));

但这样做没有意义,最好只使用set操作:

var newSet = new Set();
for(let val of set) newSet.add(myFunc(val));

或许是一个自我调用的生成器函数:

var newSet = new Set(function*() {
  for(let val of set) yield myFunc(val);
}());

答案 2 :(得分:1)

如果你绝望,你可以这样做

var str = 'abcdeaadbc';
var chars = new Set(str);
document.write("<pre>" + JSON.stringify([...chars].map(c => c+"up")) + "</pre>")