Andrew Eisenberg
Andrew Eisenberg

Reputation: 28757

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

I am using ES6 Set instances and I need to apply some transformations on them. These are transformations of the kind that would be simple if they were arrays. Here is an example:

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); // []

I was hoping that the result would either be a new Set or an array. I similarly want to use other array comprehension methods like filter, map, reduce, etc. And I would also like to have similar behaviour on ES6 Map instances as well.

Is this possible, or do I need to be using vanilla JS arrays?

Upvotes: 4

Views: 248

Answers (2)

jfriend00
jfriend00

Reputation: 707436

You can't use Array methods directly on a Set or Map object. Array methods expect .length and [n] indexing which is not how Set or Map work.

You can either convert your Set to an array using Array.from(s) or you can create your own methods to operate directly on the Set or Map. If you're going to be doing this a lot and the desired end result is a Set or Map, then it's probably better to not convert to an Array, modify, then convert back. Plus, converting a Map to an array is not quite so simple since you have both a key and value (might have to be an array of objects).

For example, you could create your own .filter() method for a Set object like this:

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(", ") +"}");

Similar methods could be created for other Array methods.

Upvotes: 1

Jaromanda X
Jaromanda X

Reputation: 1

you can get the values of s in an array using

Array.from(s.values())

Array.from documentation states that it creates a new Array instance from an array-like or iterable object.

Set.values returns a new Iterator object that contains the values for each element in the Set object in insertion order.

So your code becomes

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

Upvotes: 6

Related Questions