Vamos nos afastar das estruturas de dados individuais e falar sobre as iterações sobre elas.
No capítulo anterior vimos os métodos map.keys()
, map.values()
, map.entries()
.
Esses métodos são genéricos, existe um acordo comum para usá-los em estruturas de dados. Se algum dia criarmos nossa própria estrutura de dados, deveremos implementá-la também.
Eles são suportados para:
Map
Set
Array
Objetos simples também suportam métodos semelhantes, mas a sintaxe é um pouco diferente.
Para objetos simples, os seguintes métodos estão disponíveis:
Object.keys(obj) – retorna um array de chaves.
Object.values(obj) – retorna uma matriz de valores.
Object.entries(obj) – retorna uma matriz de pares [key, value]
.
Observe as distinções (em comparação com o mapa, por exemplo):
Mapa | Objeto | |
---|---|---|
Sintaxe de chamada | map.keys() | Object.keys(obj) , mas não obj.keys() |
Devoluções | iterável | Matriz “real” |
A primeira diferença é que temos que chamar Object.keys(obj)
, e não obj.keys()
.
Por que isso? A principal razão é a flexibilidade. Lembre-se de que os objetos são a base de todas as estruturas complexas em JavaScript. Portanto, podemos ter um objeto próprio, como data
, que implementa seu próprio método data.values()
. E ainda podemos chamar Object.values(data)
nele.
A segunda diferença é que os métodos Object.*
retornam objetos de array “reais”, não apenas iteráveis. Isso ocorre principalmente por razões históricas.
Por exemplo:
deixe usuário = { nome: "João", idade: 30 };
Object.keys(user) = ["name", "age"]
Object.values(user) = ["John", 30]
Object.entries(user) = [ ["name","John"], ["age",30] ]
Aqui está um exemplo de uso de Object.values
para fazer um loop sobre valores de propriedade:
deixe usuário = { nome: "João", idade: 30 }; //faz um loop sobre os valores for (deixe o valor de Object.values(user)) { alerta(valor); // João, então com 30 anos }
Object.keys/values/entries ignora propriedades simbólicas
Assim como um loop for..in
, esses métodos ignoram propriedades que usam Symbol(...)
como chaves.
Geralmente isso é conveniente. Mas se quisermos chaves simbólicas também, existe um método separado Object.getOwnPropertySymbols que retorna um array apenas de chaves simbólicas. Além disso, existe um método Reflect.ownKeys(obj) que retorna todas as chaves.
Os objetos não possuem muitos métodos existentes para arrays, por exemplo, map
, filter
e outros.
Se quisermos aplicá-los, podemos usar Object.entries
seguido de Object.fromEntries
:
Use Object.entries(obj)
para obter uma matriz de pares chave/valor de obj
.
Use métodos de array nesse array, por exemplo map
, para transformar esses pares chave/valor.
Use Object.fromEntries(array)
no array resultante para transformá-lo novamente em um objeto.
Por exemplo, temos um objeto com preços e gostaríamos de duplicá-los:
deixe preços = { banana: 1, laranja: 2, carne: 4, }; deixe doublePrices = Object.fromEntries ( // converte preços em array, mapeia cada par chave/valor em outro par // e então fromEntries devolve o objeto Object.entries(preços).map(entrada => [entrada[0], entrada[1] * 2]) ); alerta(doublePrices.meat); // 8
Pode parecer difícil à primeira vista, mas torna-se fácil de entender depois de usado uma ou duas vezes. Podemos fazer poderosas cadeias de transformações dessa forma.
importância: 5
Existe um objeto salaries
com número arbitrário de salários.
Escreva a função sumSalaries(salaries)
que retorna a soma de todos os salários usando Object.values
e o loop for..of
.
Se salaries
estiverem vazios, o resultado deverá ser 0
.
Por exemplo:
deixe salários = { "João": 100, "Pete": 300, "Maria": 250 }; alerta(somaSalários(salários)); //650
Abra uma sandbox com testes.
function somaSalários(salários) { seja soma = 0; for (salário de Object.values(salários)) { soma += salário; } soma de retorno; //650 } deixe salários = { "João": 100, "Pete": 300, "Maria": 250 }; alerta(somaSalários(salários)); //650
Ou, opcionalmente, também poderíamos obter a soma usando Object.values
e reduce
:
// reduz os ciclos sobre a matriz de salários, // somando-os // e retorna o resultado function somaSalários(salários) { retornar Object.values(salários).reduce((a, b) => a + b, 0) // 650 }
Abra a solução com testes em uma sandbox.
importância: 5
Escreva uma função count(obj)
que retorne o número de propriedades no objeto:
deixe usuário = { nome: 'João', idade: 30 }; alerta(contagem(usuário)); //2
Tente tornar o código o mais curto possível.
PS Ignore as propriedades simbólicas, conte apenas as “regulares”.
Abra uma sandbox com testes.
contagem de função(obj) { retornar Object.keys(obj).length; }
Abra a solução com testes em uma sandbox.