Explorando ES6: Set e WeakSet

No EcmaScript 6 foram introduzidas importantes coleções de dados que antes não existiam, uma delas, já discutida aqui no blog, foi Map e WeakMap. Hoje, discuto um pouco mais sobre duas novas e relevantes coleções que foram introduzidas no EcmaScript 6: o Set e o WeakSet.

Set

Set é uma coleção de dados onde não se permite que valor algum seja duplicado. Essa coleção também mantém a ordem dos itens conforme são inseridos e permite qualquer tipo de valor como um item.

let setDados = new Set()
let funcao = function() {}
let obj = {}
setDados.add(1)
setDados.add(1)
setDados.add(2)
setDados.add(3)
setDados.add(3)
setDados.add(4)
setDados.add(funcao)
setDados.add(obj)
for (valor of setDados){
console.log(valor) // 1, 2, 3, 4, [Function], {}
}

view raw
set.js
hosted with ❤ by GitHub

No exemplo acima vimos como Set é poderoso. Inserimos 2 itens duplicados em nosso conjunto e ele mesmo se encarregou de desconsiderá-los e removê-los de nosso set de elementos.

Você até pode arriscar a inserção de valores duplicados, porém, por debaixo dos panos, o Set irá ignorá-los!

O construtor de Set nos permite inicializá-los com vários valores pré-definidos, para isso basta utilizarmos valores dentro de um Array.

let setDados = new Set([1, "dois", 3, "quatro", 5])
for (valor of setDados){
console.log(valor) // 1, dois, 3, quatro, 5
}

view raw
set_constructor.js
hosted with ❤ by GitHub

Métodos de Set

  • add()

Há duas maneiras de adicionar elementos em um Set. Como vimos na introdução de Set, podemos adicionar elementos através do construtor em sua inicialização ou através do método add().

let set1 = new Set([1, "dois", 3, "quatro", 5])
let set2 = new Set()
set2.add(1)
set2.add(2)
set2.add(3)
set2.add(4)
set2.add(5)
for (valor of set1){
console.log(valor) // 1, dois, 3, quatro, 5
}
for (valor of set2){
console.log(valor) // 1, 2, 3, 4, 5
}

view raw
set_add.js
hosted with ❤ by GitHub

  • delete()

Para removermos elementos de um Set, podemos usar o método delete().

let setDados = new Set()
setDados.add(1)
setDados.add(2)
setDados.add(3)
setDados.delete(1)
for (valor of setDados){
console.log(valor) // 2, 3
}

view raw
set_delete.js
hosted with ❤ by GitHub

  • clear()

Se for necessário a remoção de todos os elementos de um Set deixando-o vazio, podemos usar o método clear() para isso.

let setDados = new Set()
setDados.add(1)
setDados.add(2)
setDados.add(3)
console.log(setDados.size) // 3
setDados.clear()
console.log(setDados.size) // 0

view raw
set_clear.js
hosted with ❤ by GitHub

  • size()

Para sabermos o tamanho de um Set é simples, só invocarmos o método size().

let setDados = new Set()
setDados.add(1)
setDados.add(2)
setDados.add(3)
console.log(setDados.size) // 3

view raw
set_size.js
hosted with ❤ by GitHub

  • has()

Para checarmos se um determinado elemento encontra-se em um Set, podemos utilizar o método has().

let setDados = new Set()
setDados.add(1)
setDados.add(2)
setDados.add(3)
console.log(setDados.has(2)) // true
setDados.delete(2)
console.log(setDados.has(2)) // false

view raw
set_has.js
hosted with ❤ by GitHub

Para visualização dos dados de um Set,  podemos usar os métodos entries() e values().

O output do método entries() é curioso pois lembra um mapa com chave/valor, o que acontece aqui é que esse método retorna um Iterator, assim como values(). Esse Iterator contém um array de [valor, valor] para cada elemento de Set seguindo sua ordem de inserção. Para o objeto Set não há chave/valor como em Map, contudo, para manter a API similar, cada entry possui o mesmo valor em value.

let setDados = new Set()
setDados.add(1)
setDados.add(2)
setDados.add(3)
setDados.add(4)
setDados.add(5)
for(value of setDados.values()){
console.log(value) // 1, 2, 3, 4, 5
}
for(entry of setDados.entries()){
console.log(entry) // [ 1, 1 ], [ 2, 2 ], [ 3, 3 ], [ 4, 4 ], [ 5, 5 ]
}

Para iterarmos os elementos de um Set, podemos usar tanto for.. of quanto forEach.

let setDados = new Set()
setDados.add(1)
setDados.add(2)
setDados.add(3)
setDados.add(4)
setDados.add(5)
setDados.forEach(elemento =>
console.log(elemento) // 1, 2, 3, 4, 5
)
for(elemento of setDados){
console.log(elemento) // 1, 2, 3, 4, 5
}

view raw
set_for.js
hosted with ❤ by GitHub

Como visto, os dois métodos produzem a mesma saída sempre respeitando a ordem de inserção.

WeakSet

WeakSet é um conjunto de elementos que lembra bastante o WeakMap, já falado em outro post aqui.

O que difere um WeakSet de um Set é:

  • Ele permite que apenas objetos sejam inseridos em sua coleção;
  • Ele não é um objeto iterável como Set;
  • Não é possível remover todos os elementos de uma só vez.

Lembrando que assim como WeakMap, os objetos inseridos aqui são fracamente mantidos, com isso o Garbage Colector coleta os elementos, uma vez que não haja mais referência ao mesmo. Assim que o objeto é coletado pelo GC, ele é removido de um WeakSet.

Métodos de WeakSet

WeakSet não é composto de muitos métodos como Set, portanto, aqui não temos muitas opções para manipular esse objeto. São basicamente três métodos e nenhum deles é novidade para nós em relação ao seus respectivos comportamentos. São eles: add(), has() e delete().

let weakSet = new WeakSet()
let objeto1 = {}
let objeto2 = {}
let objeto3 = {}
// método add()
weakSet.add(objeto1)
weakSet.add(objeto2)
weakSet.add(objeto3)
// método delete()
weakSet.delete(objeto1)
// método has()
console.log(weakSet.has(objeto1)) // false
console.log(weakSet.has(objeto2)) // true
console.log(weakSet.has(objeto3)) // true

view raw
weakset_methods.js
hosted with ❤ by GitHub

Para mais informações, acesse: Set – MDN / WeakSet – MDN

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google

Você está comentando utilizando sua conta Google. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s

%d blogueiros gostam disto: