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
To je vcelku jednoduché, co se ti na tom nezdá?
Wikan 28.12.2019 15:05
Wikan
Chtěl jsem to všechno dát do class ale tak jak je to napsaný to udělat nejde.
Wann 28.12.2019 15:20
Wann
Proč by to nešlo?
Wikan 28.12.2019 15:22
Wikan
Zkoušel jsem to dát celý do objektu abych to trochu odlišil od jiného kódu ale stejně to nefunguje.…
Wann 28.12.2019 15:29
Wann
No tenhle zápis je nesmysl. Ale psal jsi, že to chceš dát do třídy a teď píšeš o objektu. Asi by sis…
Wikan 28.12.2019 15:31
Wikan
A proč je to nesmysl, je tam špatná syntaxe nebo to nejde použít v jednom objektu? Je mi to asi jedn…
Wann 28.12.2019 15:39
Wann
1. Máš tam špatně závorky. 2. Nemůžeš použít this.property pro inicializaci jiné property, protože t…
Wikan 28.12.2019 15:54
Wikan
Takto? Ale závorky jsem nenašel :( var obj = { items: [{id: 45,lable: "Test 1.2.1",parent_id: 2}, {…
Wann 28.12.2019 16:07
Wann
Hned první složená za "items: []" je tam navíc. Proč se tam pořád snažíš protlačit tenhle zápis, kdy…
Wikan 28.12.2019 16:14
Wikan
Nejde jako že to nejde ani opravit? Tak to jsem nepochopil. A dát to do jedné class jde, nebo taky n…
Wann 28.12.2019 16:20
Wann
Dát to do jedné třídy to samozřejmě jde. Ale není to zbytečné, když to můžeš dát do jedné funkce?
Wikan 28.12.2019 16:24
Wikan
Do jedené funkce všechno? To jde? To by bylo úplně nejlepší.
Wann 28.12.2019 16:29
Wann
Samozřejmě. Proč by to nešlo? JS nedávno ještě třídy vůbec neměl a místo nich se používaly funkce.
Wikan 28.12.2019 16:32
Wikan
A můžeš mi s tím pomoci? Jelikož vůbec nevím jak to myslíš.
Wann 28.12.2019 17:03
Wann
Prostě celý ten původní kód obal funkcí.
Wikan 28.12.2019 17:20
Wikan
Nechápu, jako takto? function MojeFunkce () { var obj = { items: [{ id: 45, lable: "Test 1.2.1", p…
Wann 28.12.2019 17:57
Wann
Tak to jsem si tím opravdu pomohl..
Wann 28.12.2019 20:25
Wann
A co se ti na tom nezdá?
Wikan 28.12.2019 20:31
Wikan
No netuším jak ty funkce uvnitř volat :-D
Wann 28.12.2019 20:50
Wann
Ale ty je nijak volat nepotřebuješ. Zavoláš tu nadřazenou a hotovo. nový
Wikan 28.12.2019 20:51
Wikan
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);
    }
  }
}

Zkoušel jsem to dát celý do objektu abych to trochu odlišil od jiného kódu ale stejně to nefunguje.


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
        }]
      },
      
      objDict : this.items.reduce(function(p, c) {
        p[c.id] = c;
        c.children = [];
        return p;
      }, {}),
      
      tree : this.items.reduce(function(p, c) {
        if (!c.parent_id) {
          p = c;
        } else {
          this.objDict[c.parent_id].children.push(c);
        }
        return p;
      }, {}),
      
      processTree : function (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++) {
            this.processTree(node.children[i], ul);
          }
        }
      }

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

A proč je to nesmysl, je tam špatná syntaxe nebo to nejde použít v jednom objektu?
Je mi to asi jedno, používat místo tříd objekty které se všechny vytvoří hned při načtení stránky.
Nejde mi ani tak o objekty, moc s nimi neumím pracovat, slouží to spíš jako takový namespace ;)
Funkce jsou jistota ale kilometrové názvy funkcí se fakt nedají používat.

Takto? Ale závorky jsem nenašel :(

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}]
      },

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

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

      processTree : function (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++) {
            this.processTree(node.children[i], ul);
          }
        }
      }

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

Nechápu, jako takto?


function MojeFunkce ()
{
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