26. ledna 2025

Metody Object.keys, values, entries

Odhlédněme nyní od individuálních datových struktur a promluvme si o iteracích nad nimi.

V předchozí kapitole jsme viděli metody mapa.keys(), mapa.values(), mapa.entries().

Tyto metody jsou generické, existuje společná dohoda ohledně jejich používání pro datové struktury. Jestliže si sami vytvoříme vlastní datovou strukturu, měli bychom je implementovat také.

Jsou podporovány v:

  • mapách (Map)
  • množinách (Set)
  • polích (Array)

Podobné metody jsou podporovány i v planých objektech, ale jejich syntaxe je trochu jiná.

Object.keys, values, entries

Pro plané objekty jsou k dispozici následující metody:

Prosíme, všimněte si rozdílů (například ve srovnání s mapou):

Mapa Objekt
Syntaxe volání mapa.keys() Object.keys(obj), ale ne obj.keys()
Vrací iterovatelný objekt „opravdové“ pole

Prvním rozdílem je, že musíme volat Object.keys(obj), ne obj.keys().

Proč tomu tak je? Hlavním důvodem je flexibilita. Pamatujte, že objekty jsou základem všech složitých struktur v JavaScriptu. Můžeme tedy mít svůj vlastní objekt, např. data, který implementuje svou vlastní metodu data.values(). A přesto na něm můžeme volat Object.values(data).

Druhým rozdílem je, že metody Object.* vracejí „opravdová“ pole, ne jen iterovatelné objekty. Tak tomu je zejména z historických důvodů.

Příklad:

let uživatel = {
  jméno: "Jan",
  věk: 30
};
  • Object.keys(uživatel) = ["jméno", "věk"]
  • Object.values(uživatel) = ["Jan", 30]
  • Object.entries(uživatel) = [ ["jméno","Jan"], ["věk",30] ]

Zde je příklad použití Object.values k vytvoření cyklu nad hodnotami vlastností:

let uživatel = {
  jméno: "Jan",
  věk: 30
};

// cyklus nad hodnotami
for (let hodnota of Object.values(uživatel)) {
  alert(hodnota); // Jan, poté 30
}
Object.keys/values/entries ignorují symbolické vlastnosti

Stejně jako cyklus for..in, i tyto metody ignorují vlastnosti, jejichž klíčem je Symbol(...).

Zpravidla nám to vyhovuje. Jestliže však chceme i symbolické klíče, existuje samostatná metoda Object.getOwnPropertySymbols, která vrací pole výhradně symbolických klíčů. Existuje i metoda Reflect.ownKeys(obj), která vrací všechny klíče.

Transformace objektů

Objekty postrádají mnohé metody, které existují pro pole, např. map, filter a jiné.

Pokud je chceme použít, můžeme použít Object.entries, po níž bude následovat Object.fromEntries:

  1. Použijte Object.entries(obj) k získání pole dvojic klíč/hodnota z obj.
  2. Na tomto poli použijte metody polí, např. map, která tyto dvojice klíč/hodnota transformuje.
  3. Na výsledné pole volejte Object.fromEntries(pole), která z něj opět udělá objekt.

Například máme objekt s cenami a rádi bychom je zdvojnásobili:

let ceny = {
  banán: 1,
  pomeranč: 2,
  maso: 4,
};

let dvojnásobnéCeny = Object.fromEntries(
  // převedeme na pole, zmapujeme každou dvojici klíč/hodnota na jinou dvojici
  // a pak nám funkce fromEntries znovu vytvoří objekt
  Object.entries(ceny).map(prvek => [prvek[0], prvek[1] * 2])
);

alert(dvojnásobnéCeny.maso); // 8

Na první pohled to může vypadat obtížně, ale jakmile to jednou nebo dvakrát použijete, bude snadné tomu porozumět. Tímto způsobem můžeme vytvořit silné řetězce transformací.

Úlohy

důležitost: 5

Máme objekt prodeje obsahující libovolný počet prodejů.

Napište funkci sečtiProdeje(prodeje), která vrátí součet všech prodejů, přičemž bude využívat Object.values a cyklus for..of.

Je-li objekt prodeje prázdný, výsledek musí být 0.

Příklad:

let prodeje = {
  "Jan": 100,
  "Petr": 300,
  "Marie": 250
};

alert( sečtiProdeje(prodeje) ); // 650

Otevřít pískoviště s testy.

function sečtiProdeje(prodeje) {

  let součet = 0;
  for (let prodej of Object.values(prodeje)) {
    součet += prodej;
  }

  return součet; // 650
}

let prodeje = {
  "Jan": 100,
  "Petr": 300,
  "Marie": 250
};

alert( sečtiProdeje(prodeje) ); // 650

Nebo volitelně můžeme také získat součet použitím Object.values a reduce:

// reduce cykluje nad polem prodejů,
// sečte je
// a vrátí výsledek
function sečtiProdeje(prodeje) {
  return Object.values(prodeje).reduce((a, b) => a + b, 0) // 650
}

Otevřít řešení s testy na pískovišti.

důležitost: 5

Napište funkci spočítej(obj), která vrátí počet vlastností v objektu:

let uživatel = {
  jméno: 'Jan',
  věk: 30
};

alert( spočítej(uživatel) ); // 2

Snažte se napsat kód co nejkratší.

P.S. Ignorujte symbolické vlastnosti, počítejte jen „obyčejné“.

Otevřít pískoviště s testy.

function spočítej(obj) {
  return Object.keys(obj).length;
}

Otevřít řešení s testy na pískovišti.

Mapa tutoriálu

Komentáře

přečtěte si před komentováním…
  • Máte-li návrhy na zlepšení, vytvořte prosím issue na GitHubu nebo pull request místo komentáře.
  • Pokud v článku něčemu nerozumíte, napište prosím, čemu přesně a na kterém místě.
  • Pro vložení několika slov kódu použijte značku <code>, pro několik řádků je obalte značkou <pre>, pro více než 10 řádků vložte odkaz na pískoviště (plnkr, jsbin, codepen…)