The Set
is a object that allows setar unique values.
You can start a Set
empty, or start already with some content from the constructor:
let foo = new Set([1, 2, 3, 4, 5]);
foo.add(6);
console.log(foo.entries());
Will return:
SetIterator {1, 2, 3, 4, 5, 6}
Iterating a Set
The .entries
can be used in a for
to iterate, just as you can use the method .forEach
of the own Set
, thus:
//O primeiro e o segundo argumento tem o mesmo valor
//o terceiro retorna o Set atual, pode ser interessante se usar a função para diferentes Sets
foo.forEach(function (valor1, valor2, currentSet) {
console.log('set[' + chave + '] = ' + valor);
console.log(currentSet); //Exibe o Set atual
});
Note that the forEach
has a second argument:
.forEach(callback [, thisArg])
In place of thisArg
you can put something else so that the this
inside the callback is what you defined, as being the this
of the above scope, example:
let foo = new Set([1, 2, 3, 4, 5]);
document.querySelector("#test").onclick = function () {
foo.forEach(function (v1, v2, thisArg) {
console.log(v1, v2, this);
}, this);
};
<button id="test">Testar</button>
Another way to iterate is to use your own Set
directly within a for...of
(or for...in
, although this second has no advantage, since we only care about the value):
for (let valor of foo) {
console.log(valor);
}
I believe that this way is even cleaner than using .entries
or .forEach
, the advantage of .forEach
even would be the use of callbacks
dynamics, so instead of writing three lines like this:
for (let valor of foo) {
meuCallback(valor);
}
You would write only one like this:
foo.forEach(meuCallback);
Then you can use for...of
when it’s just iterate and forEach
when you have dynamic callbacks.
Support for the Set
According to the MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/forEach
The browsers that support are:
- Chrome 38+
- Edge 12+
- IE 11+ (miraculously, I didn’t expect this)
- Safari 8+
- Firefox 25+
If you don’t have support in all browsers, there is some Polyfill?
I’ll be honest, and take this as a personal opinion, Polyfill for this seems a bit of an exaggeration, it’s serious, as the intention is to create single values a simple check with Array.indexOf
would already resolve before adding to an Array something, for example:
var x = [1,2,3];
//Supondo que este if seja executado por um callback e que os dados sejam dinamicos
var novo = 3;
if (x.indexOf(novo) === -1) {
x.push(novo);
} else {
console.log('Já adicionado');
}
But if you think you’re gonna use this on a lot of things, maybe a polyfill is useful. Once you test the polyfills mentioned in the comments and make sure they work well I will add here (I don’t usually add something that I haven’t tested at least once).
Converting to Array or Arguments
To convert to array you can use the three dots (this is called Spread syntax and this nay is supported in Internet Explorer), thus:
let foo = new Set([1, 2, 3, 4, 5]);
let arr = [...foo];
console.log(arr);
Or you can pass to arguments of a function like this
let foo = new Set([1, 2, 3, 4, 5]);
teste1(...foo);
teste2(...foo);
//Especificos
function teste1(a, b, c, d) {
console.log("test1:", a, b, c, d);
}
//usando "arguments"
function teste2() {
console.log("test2:", arguments);
}
Support for the Spread:
- Chrome 46+
- Edge 12+
- Firefox 16+
- Safari 8+
Another way is by using the Array.from
:
Array.from(foo);
Support:
- Chrome 45+
- Edge (apparently all versions)
- Firefox 32+
- Safari 9+
Details about the Set
What values can I add to a Set object?
Anything even that could add to a variable or array, it works as an array itself, but simply has the detail of the control of single values
I can have a string and int collection in the same Set object?
Yeah, can stand anything, can even have Set
inside Set
, but one thing needs to be clear, the added values of Objects are like references, ie the value is not copied it is referenced, this in Arrays and Object too, because this is how Javascript is, of course you can copy/clone an entire object, but this is another story.
What is the criterion for determining whether an element already belongs to the Set object?
You can use the .has
, it is worth noting that it is as said, it is all as reference, so for example:
var a = {};
var b = {};
console.log(a === b); //Retorna FALSE
Although similar are different objects, so in doing this:
var a = {};
var meuSet = new Set;
meuSet.add(a);
console.log(meuSet.has({})); //Retorna FALSE
console.log(meuSet.has(a)); //Retorna TRUE
The meuSet.has(a)
returns TRUE because it checks the object itself referenced in the variable a
, This has nothing to do with the Set
, but yes how Javascript works (such behavior is similar in many languages)
@Andersoncarloswoss has carte blanche to edit :p
– Wallace Maxters