View on GitHub

Capacitacao-CEOS-2-Javascript

Estruturas de Dados

Em algumas linguagens de programação, existem algumas estruturas de dados muito comuns, como Arrays. Já vimos os Arrays, porém Javascript também vem com Maps e Sets já inclusos.

Sets são como conjuntos na matemática: um conjunto de valores, porém sem repetição. Ou seja, em um Array normal, podemos ter elementos repetidos: [1, 2, 1, 2]. Porém em um Set, não teriamos essa repetição.

Outra diferença importante, é que Sets não usam indices para armazenar os valores, a gente simplesmente insere eles no conjunto, sem se preocupar com um índice.

Podemos criar um novo Set vazio fazendo let set = new Set();. Essa palavra new será aprofundada nos próximos capitulos (no capitulo 16 - Class).

Para inserir elementos no Set, podemos usar o método set.add(valor). Podemos por qualquer elemento em um Set: números, strings, até mesmo objetos ou outros Sets.

Exemplo:

let set = new Set();
set.add(1);
set.add(2);
set.add("frase");

Para verificar se já existe algum elemento no Set, podemos usar o método set.has(valor);

Exemplo:

let set = new Set();
set.add(1);

console.log(set.has(1)); // true

Também podemos remover um elemento de um Set, usando set.delete(valor).

Exemplo:

let set = new Set();
set.add(1);

console.log(set.has(1)); // true

set.delete(1);

console.log(set.has(1)); // false

Para iterarmos em cada elemento do Set, isto é, ler cada valor que está no Set, podemos usar o método set.forEach(funcao).

Esse método é similar ao método Array.forEach que estudamos em capitulos anteriores, ele recebe uma função que vai ser chamada pelo Javascript, e essa função recebe três parâmetros:

Exemplo - imprimindo todos os elementos de um Set:

let set = new Set();

set.add(1);
set.add(2);
set.add("3");
set.add(2);

function imprimeElementos(valor, chave, set) {
    console.log(valor);
}

set.forEach(imprimeElementos);

// 1
// 2
// "3"

Perceba no exemplo acima que embora adicionamos o valor 2 2 vezes, ele só aparece 1 vez, pois não temos elementos repetidos em um Set. Também perceba que o segundo argumento da função imprimeElementos se chama chave, dei esse nome para seguir a documentação da MDN, que explica melhor esse método.

E é assim que podemos utilizar Sets em Javascript. Outros métodos úteis para Sets podem ser encontrados diretamente na documentação da MDN.

Também existe uma estrutura de dados extremamente útil: Map.

Em linguagens como Java, usamos Maps para fazer um mapeamento chave-valor.

Ok, isso pode lembrar um pouco da sintaxe de objetos em Javascript, pois ela também realiza um mapeamento chave-valor.

Porém, existem algumas diferenças entre Maps e Objects no Javascript.

Usando objetos, nós só podemos ter identificadores comum de variáveis, ou no máximo strings como uma chave.

Exemplo:

let meuObjeto = {};

meuObjeto.chave1 = "bla";
meuObjeto["chaveDoidera"] = "hm";
meuObjeto["chave mais Louca ainda"] = "eita";

Usando strings, temos um pouco mais de flexibilidade para nossas chaves. Porém, usando a sintaxe de ., podemos ter erros se a nossa chave contém espaços, e também não podemos ter chaves como outros objetos por exemplo.

O código abaixo resulta em um erro.

let meuObjeto = {};

meuObjeto.chave com espaco = "bla";

Porém, com Map, podemos usar tanto valores primitivos quando objetos como chaves, e também temos alguns métodos extremamente úteis, que não possuimos se tivermos apenas um Object para fazer mapeamento chave-valor.

Para inicializar um Map vazio, podemos fazer let map = new Map();

Para adicionar um par chave-valor no mapa, devemos usar o método map.set(chave, valor).

Lembrando que as chaves e os valores podem ser de qualquer tipo, quando estivermos utilizando um Map.

let map = new Map();

map.set("chave1", "valor1");

let chaveObjeto = {nome: "chave maneira};

map.set(chaveObjeto, "uau");

Um detalhe muito importante sobre o método map.set: se uma chave já tiver sido inserida, e for inserida novamente, o valor anterior será sobrescrito.

Exemplo:

let map = new Map();

map.set("chave1", "valor1");
map.set("chave1", "uau");

// agora o valor ligado a chave "chave1" é a string "uau"

Para obter o valor ligado a uma chave, usamos map.get(chave).

Exemplo:

console.log(map.get("chave1")); // "valor1"
console.log(map.get(chaveObjeto)); // "uau"

É possível verificar se existe uma determinada chave em um mapa, usando o método map.has.

Exemplo:

let map = new Map();
map.set("chave", "valor");

console.log(map.has("chave")); // true
console.log(map.has("chaveDiferente")); // false

Também é possível verificar quantos elementos foram inseridos em um Map, utilizando a propriedade map.size.

Exemplo:

let myMap = new Map();
myMap.set("a", "alpha");
myMap.set("b", "beta");
myMap.set("g", "gamma");

console.log(myMap.size); // 3

Por fim, também temos o método map.forEach(funcao), que atua de forma similar ao método set.forEach(funcao).

Esse método espera receber como parâmetro uma função com 3 parâmetros:

Vamos a um exemplo: mostrando todos os pares chave-valor que estão inseridos em um Map.

let myMap = new Map();
myMap.set("a", "alpha");
myMap.set("b", "beta");
myMap.set("g", "gamma");

function mostraChaveValor(valor, chave, objetoMap) {
    console.log(chave + " - " + valor);
}

myMap.forEach(mostraChaveValor);

Execute essa função e veja o resultado :)

Bem, temos essas duas estruturas de dados em Javascript, elas são úteis em algumas situações, então é útil conhecer elas.

Tenha cautela na diferença entre Map e um Object comum. Map é bem mais flexível no quesito das chaves, e também vem com uma série de métodos utilitários, que auxiliam no mapeamento e operações envolvendo chave-valor, portanto, utilize com sabedoria :)