JSON-ban tárolt értékek feldolgozása egy új objektumban
2019-05-11T16:55:15+02:00
2019-05-11T18:44:08+02:00
2022-08-11T12:30:30+02:00
juzzie
Sziasztok!

Lenne egy problémám, amit szeretnék megoldani JS-ben. Adva van egy egyszerű JSON fájl:

{ "masks": { "folder": "Mappa" }, "index": { "fields": { "folderId": "INDEX" }, "values": { "folderId": "halihó" } } }
A JSON fájl adatai már fel parse-olva objektumként érkezik meg egy JS függvénybe paraméterként (cfg). példa:

console.log(cfg.masks.folder) // "Mappa" console.log(cfg.index.fields.folderId) // "INDEX" console.log(cfg.index.values.folderId) // "halihó"
Itt három érteket kapok meg, ami a JSON-ból érkezik. De a függvény még kap egy tömb paramétert, amiben megadok új változókat: ["first", "second", "third"]. Persze ez módosítható.

Azt szeretném eredményként, hogy egy másik objektum, neve legyen result kapják meg ezt értékül:

result.first // "Mappa"
result.second // "INDEX"
result.third // "halihó"

Viszont a result objektumnak van még két tagja. Az első az "error", ami alapértelmezetten false értéket vesz fel. Ha elírás van a cfg objektumnál (pl.: cfg.nasks.folder) és nem egyenlő a JSON-ban található megnevezéssel, akkor az "error" értéke true lesz. A másik tag a "message", ebben tarolódik, hogy melyik érték átadásával van a probléma (pl. "first" vagy "second"). Ez egy ellenőrző függvény lenne. A hiba kezelés igazából már kész és működik, de a result objektum megvalósításba beletört a bicskám!

A függvény hívása után ellenőrzöm, hogy van-e hiba. Ha nincs, akkor megy tovább és a result objektum tartalmazza a fenti három változója az értékeket, ha igen, akkor kiíratom a result.message értékét.

A segítséget előre is köszönöm.
Üdv.
Mutasd a teljes hozzászólást!
Hali!

Bár ha lenne egy megoldás arra, hogy a cfgobjektumon végig tudnék menni úgy, hogy az összes változót kitudom szedni, arra még nem is gondoltam.

Na, mintha valami világosabb lenne.  Ha nem értem még mindig félre, akkor egy objektum tulajdonságait szeretnéd megkapni paraméterként megadott „útvonalak” (az illető adattagok elérése) alapján. Első lépésként készíthetnél az induló objektumodból egy „flat” verziót, azaz kilőnéd az egymásba ágyazottságot. Pl.:
var json = { "masks": { "folder": "Mappa" }, "index": { "fields": { "folderId": "INDEX" }, "values": { "folderId": "halihó" } } }; function toFlat(obj, path) { const result = {}; Object.keys(obj).forEach((key) => { const newKey = (path !== undefined ? path + '.' : '') + key; if (typeof obj[key] === 'object' && obj[key] !== null) { Object.assign(result, toFlat(obj[key], newKey)); } else { result[newKey] = obj[key]; } }); return result; }; var newJson = toFlat(json);
Így a hívás után a newJson objektumban a következő eredményt kapnád:
{ "masks.folder": "Mappa", "index.fields.folderId": "INDEX", "index.values.folderId": "halihó" }
Ezen pedig már könnyen végig tudsz lépkedni (akár csak egymás után véve az értékeket, akkor összehasonlítva az adattagok nevét a paraméterként megadott „útvonalakkal”).
Mutasd a teljes hozzászólást!

  • Hali!

    Azt szeretném eredményként, hogy egy másik objektum, neve legyen result kapják meg ezt értékül:

    result.first // "Mappa"
    result.second // "INDEX"
    result.third // "halihó"

    Mi a megfeleltetés szabálya? Mitől függ, hogy ha 'first' a paraméter értéke, akkor a 'cfg.masks.folder' értéket szeretnéd megkapni?

    Mutasd a teljes hozzászólást!
  • Szia!

    Értem a kérdést! Ezt elfelejtettem leírni, hogy a hibakezelés így néz ki:

    result.error = false; try { verify.push({ value: cfg.masks.folder }); verify.push({ value: cfg.index.fields.folderId }); verify.push({ value: cfg.index.values.folderId }); for (i = 0; i < verify.length; i++) { if (typeof verify.value == "undefined") { result.error = true; result.message = keys; } } } catch (err) { result.error = true; result.message = keys[verify.length]; }
    Vagyis a két tömb (keys és verify) sorrendje!

    Köszönöm előre is a segítséget!
    Mutasd a teljes hozzászólást!
  • én nem egészen értem, de talán:

    result[keys[i]] = verify[i].value
    Mutasd a teljes hozzászólást!
  • Hali!

    Értem a kérdést!

    Az jó, ellenben én továbbra sem értem, hogy mi alapján szeretnéd visszakapni az értékeket (vagy valamit nagyon benézek). Tehát, ha a nyitó hozzászólásodban megadott (JSON-)objektumot vesszük, illetőleg a példaként megadott ["first", "second", "third"] tömböt, akkor mi alapján szeretnéd, hogy az eredmény-objektumod 'first' adattagja az eredeti objektum 'mask.folder' értéke, az eredmény-objektumod 'second' adattagja az eredeti objektum 'index.fields.folderId' értéke és az eredmény-objektumod 'third' adattagja az eredeti objektum 'index.values'.folderId' értéke legyen? Mi a megfeleltetés szabálya?

    Mutasd a teljes hozzászólást!
  • Szia!

    Az első paraméter a cfg objektum első értéke megy bele a verify tömbbe:

    verify.push({ value: cfg.masks.folder });

    A másik paraméter a keys tömb. Mind a két tömb azonos elemszámmal fog rendelkezni. Vagyis egy ciklussal összepárosítom őket. Bár ha lenne egy megoldás arra, hogy a cfg objektumon végig tudnék menni úgy, hogy az összes változót kitudom szedni, arra még nem is gondoltam.

    Üdv.
    Mutasd a teljes hozzászólást!
  • Hali!

    Bár ha lenne egy megoldás arra, hogy a cfgobjektumon végig tudnék menni úgy, hogy az összes változót kitudom szedni, arra még nem is gondoltam.

    Na, mintha valami világosabb lenne.  Ha nem értem még mindig félre, akkor egy objektum tulajdonságait szeretnéd megkapni paraméterként megadott „útvonalak” (az illető adattagok elérése) alapján. Első lépésként készíthetnél az induló objektumodból egy „flat” verziót, azaz kilőnéd az egymásba ágyazottságot. Pl.:
    var json = { "masks": { "folder": "Mappa" }, "index": { "fields": { "folderId": "INDEX" }, "values": { "folderId": "halihó" } } }; function toFlat(obj, path) { const result = {}; Object.keys(obj).forEach((key) => { const newKey = (path !== undefined ? path + '.' : '') + key; if (typeof obj[key] === 'object' && obj[key] !== null) { Object.assign(result, toFlat(obj[key], newKey)); } else { result[newKey] = obj[key]; } }); return result; }; var newJson = toFlat(json);
    Így a hívás után a newJson objektumban a következő eredményt kapnád:
    { "masks.folder": "Mappa", "index.fields.folderId": "INDEX", "index.values.folderId": "halihó" }
    Ezen pedig már könnyen végig tudsz lépkedni (akár csak egymás után véve az értékeket, akkor összehasonlítva az adattagok nevét a paraméterként megadott „útvonalakkal”).
    Mutasd a teljes hozzászólást!
  • Szia szbzs.2!

    Köszönöm a választ ezt már én is alkalmaztam, csak picit másként:

    var result = {}; for (i = 0; i < verify.length; i++) { Object.defineProperty(result, keys, { value: verify.value, writable: false }); }
    Mutasd a teljes hozzászólást!
  • Hmm.. Ezt elfogadom válaszként, mert egy szinttel tovább is léptünk. :) Nagyon jó megoldás, mert később a JSON módosításánál, bővítésénél is hasznos.

    Nagyon szépen köszönöm a segítséget!
    Mutasd a teljes hozzászólást!
abcd