Yuriy Yakym Yuriy Yakym - 2 years ago 75
Javascript Question

Why can't I invoke Array.prototype.map with Set object

I want to get get unique characters from some string using ES6's Set.
So let's assume that we have string

var str = 'abcdeaabc';
and create set of characters from this string:

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

Now we have the set of unique characters:
I was surprised that
set has
method and has no

Set is iterable object, so why can't we use
function to iterate over set?

I tried to pass
set and
SetIterator to
this way:

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

But every try failed.

For example, let's assume that we want to get unique symbols from string and return an array of them with preceding underscore. eg.:
['_a', '_b', '_c', '_d']

Here are my two solutions:

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

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

But is there a way of invoking Array.prototype's
function with
context? And if no - why?

Answer Source

Array.prototype.map works on array-like types that have integer indexes and a length property. Set and Map are general iterable types, but they are not array-like, so Array.prototype methods will not work on them. e.g.

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

The main approach is Array.from kind of like your solution, but one thing to note is that Array.from takes a mapFn as the second argument, so you can do

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

for a nice and short map to convert an iterable to an array.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download