Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailem Objasnění zápisu v JS

Ahoj,
co je prosím tohle za zápis?

var tree = o.i.reduce(function(a,b){
  /*
  moj kod
  */
}, {});

a proč tohle už nefunguje

var tree = o.i.reduce(function(a,b){
  /*
  moj kod
  */
});

Děkuji

PS: šlo by to zapsat líp?

Jsou zobrazeny jen nové odpovědi. Zobrazit všechny
Předmět Autor Datum
Protože ten tvůj kód nejspíš pracuje s počáteční hodnotou (to je ten druhý parametr). A jestli to jd…
Wikan 28.12.2019 13:50
Wikan
Tady je to celý jestli to pomůže create-a-nested-list-from-a-object var obj = { items: [{ id: 45,…
Wann 28.12.2019 14:55
Wann
Tento kód má niekoľko častí: 1. Definovanie dát s položkami priradených do objektu obj. 2. Priprave… poslední
moose 29.12.2019 14:37
moose

Tady je to celý jestli to pomůže

create-a-nested-list-from-a-object

var obj = {
  items: [{
    id: 45,
    lable: "Test 1.2.1",
    parent_id: 2
  }, {
    id: 12,
    lable: "Test 1.0",
    parent_id: 0
  }, {
    id: 32,
    lable: "Test 1.1",
    parent_id: 12
  }, {
    id: 2,
    lable: "Test 1.2",
    parent_id: 12
  }]
}

var objDict = obj.items.reduce(function(p, c) {
  p[c.id] = c;
  c.children = [];
  return p;
}, {});

var tree = obj.items.reduce(function(p, c) {
  if (!c.parent_id) {
    p = c;
  } else {
    objDict[c.parent_id].children.push(c);
  }
  return p;
}, {});

processTree(tree, document.getElementById("list"));

function processTree(node, element) {
  var li = document.createElement('li');
  li.innerText = node.lable;
  element.appendChild(li);
  if (node.children.length) {
    var ul = document.createElement('ul');
    li.appendChild(ul);
    for (var i = 0; i < node.children.length; i++) {
      processTree(node.children[i], ul);
    }
  }
}

Tento kód má niekoľko častí:

1. Definovanie dát s položkami priradených do objektu obj.
2. Pripravenie slovníka objDict tak, aby sa dalo jednoducho dostať k položke podľa jej identifikátora. Súčasne sa inicializuje vlastnosť children daných položiek.
3. Naplnenie detí položiek do vlastnosti children. Súčasne sa vyhľadá koreňový uzol (taký, ktorý nemá rodiča; použije sa posledný nájdený; ak sa nenájde, koreňovým uzlom je prázdny objekt).
4. Vytvorenie HTML elementov podľa danej štruktúry.

Ak tomu chceš dať nejakú štruktúru, tak by som nad tým rozmýšľal tak, že v podstate účelom toho kódu je vyrenderovať strom podľa daných dát. Parametrami by mali byť dáta (ktoré chceš zobraziť) a element (do ktorého chceš tie dáta zobraziť).

Z toho mi vychádza, že chceš mať jednu funkciu renderTree(data, ulElement). Takže by som presunul tie var objDict a var tree do funkcie processTree a príslušne upravil zvyšok kódu.

Ak to chceš mať v "mennom priestore", tak tú funkciu zabaľ do objektu, napr. const treeRenderer = { renderTree: function(...) { ... } };

Prípadne ak to chceš mať v triede, tak to zabaľ do triedy: class TreeRenderer { renderTree(...) { ... } }. Voliteľne môžeš deklarovať metódu ako static, ak nechceš vytvárať inštanciu triedy.

Z pohľadu čitateľnosti by stálo za to upraviť kód tak, aby sa nemiešali dve rôzne veci v jednom kroku. T.j. napr. v kroku 2 by mal byť jeden krok vytvorenie mapy a druhý inicializácia children:
- const itemsById = new Map(obj.items.map(item => [item.id, item]));
- obj.items.forEach(item => item.children = []);

Prípadne možno ešte lepšie by bolo vytvoriť si štruktúru vedľa a nemodifikovať dáta. V tom prípade by si mohol inicializovať aj deti v jednom kroku, pretože by to bolo súčasťou jedného logického kroku pre prípravu takejto štruktúry:
- const itemsById = new Map(obj.items.map(item => [item.id, { item, children: [] }]));

Podobne by sa dal upraviť krok 3.

Ďalej by som sa vyhol použitiu var. V súčasnosti je var typicky iba v legacy kóde a namiesto toho sa používa const a let (ak niečo môžeš deklarovať ako const, tak použi const, a let použi iba v ostatných prípadoch).

Zpět do poradny Odpovědět na původní otázku Nahoru