NEWS
JSON Objekte in Liste
-
@mickym sagte in JSON Objekte in Liste:
Wie gesagt - Rechne mir bitte EIN Objekt mit den beiden Zählerständen vor, wie Du es haben möchtest.
In diesem Beitrag habe ich versucht, die Aufgabenstellung zu reduzieren. Sinnvollerweise sollte man wohl ein leeres Element (Energiepries=0 und Wert=0) in jedem ARRAY Bezug, Verbrauch und Verkauf einführen, um über alles Differenzen zwei aufeinander folgender Werte zu summieren.
In JSONata fand ich bisher keine Kontrollstrukturen, die so etwas ermöglichen. Hier muss ich dann wohl doch noch mit Blockly ran.
Da ich ja nur immer eine Summe für jedes ARRAY getrennt haben muss, habe ich die Datenstruktur und Abfrage wie hier ausgeführt geändert.
Nun ja, ich habe mich für den Anfang wohl schlichtweg übernommen. Erst einmal kleiner Brötchen backen, wäre wohl besser.
-
@legro Nun bitte sehr: https://try.jsonata.org/lM8bWJD1Q
Hier war dein Array
[0,2,4,7,9]
und das sind die Differenzen
[ 2, 2, 3, 2 ]
und die Summe ist dann 9
Ok - ich verstehe, da hast zum Schluss mehr als 2 Elemente in Deinen Arrays. Trotzdem ist der 1. Preis immer irrelevant.
-
@legro Ja das Problem ist dass Dein Array ja wächst, deswegen dürfen wir nicht mit fixen Indizes arbeiten. Ich überlege noch.
-
Ok - ich verstehe, da hast zum Schluss mehr als 2 Elemente in Deinen Arrays. Trotzdem ist der 1. Preis immer irrelevant.
Daher ja auch die Idee eine "leeren Elementes", damit die Iteration gelingt.
-
@legro Ja passt schon - wir könnten das auch mit Codieren in JSONATA lösen - aber ich tüftle noch.
-
@mickym sagte in JSON Objekte in Liste:
@legro Ja passt schon - wir könnten das auch mit Codieren in JSONATA lösen - aber ich tüftle noch.
Ich bin voller Bewunderung!
Allerdings verstehe ich noch nicht die Syntax in dem Ausdruck $#$i.[$$[$i+1]-$$[$i]] Da muss ich noch kräftig nachdenken.
-
-
@legro Ja wie gesagt das nützt nichts, ich gehe ja davon aus, dass Dein Array weiter wächst.
-
@mickym sagte in JSON Objekte in Liste:
@legro Ja wie gesagt das nützt nichts, ich gehe ja davon aus, dass Dein Array weiter wächst.
Wenn ich in dem Beispiel-ARRAY mit den Zahlen Elemente ergänze, wird doch alles dynamisch bereits berücksichtigt. Das Ganze funktioniert doch schon wie gewünscht. Oder wo liegt mein Denkfehler?
-
@legro Ja da funktioniert es auch aber ich komme mit den Objekten noch nicht klar - ich versuch das nun mal mit bissi Code. Hab einfach bissi Geduld.
-
@mickym sagte in JSON Objekte in Liste:
@legro Ja da funktioniert es auch aber ich komme mit den Objekten noch nicht klar - ich versuch das nun mal mit bissi Code. Hab einfach bissi Geduld.
Du kannst gerne alle Zeit der Welt haben. Wenn du bei der Anpassung an meinen Beispielcode noch überlegen muss, habe ich gar keinen Mut das Beispiel daraufhin zu erweitern.
Kannst du bitte die neue Struktur verwenden?
-
@legro Ja mach ich
-
So ich habs fertig.
Deine Formel stimmt meines Erachtens auch nicht - aber so dürfte das nun gehen.
https://try.jsonata.org/p-SrPKlgy
Die Summe ist nun: 1213.29
(gerundet)
Wenn Du die Aufsummierung weglässt, siehst Du das Ergebnis jedes Blocks:
[ 190.3172341, 0, 1022.9705301 ]
Grundsätzlich würde ich aber mit Sonderzeichen aufpassen - also Umlauten auch wenn es hier im Moment kein Problem gibt
Man kann das Ganze auch ohne Programm schreiben:
https://try.jsonata.org/AUkOIVcjP
ABER - deine 1. Struktur war viel besser. ....
damit geht es in einer Zeile: https://try.jsonata.org/1lDqzoiKc
Das liegt daran weil Du das Objekt Stände benannt hast. Sowas ist wesentlich besser, als unbenannte Objekte in einem Array aneinanderzureihen. Ich hätte auch deine jetzige Struktur in die alte Struktur überführen können, hängt halt davon ab, wie Du die erzeugst.
Nachtrag:
Im Prinzip ist es egal - ob Du mit einem 0 Wert anfängst oder nicht - es wird halt immer brav die Differenz zwischen einem Objekt und seinem Vorgänger ermittelt und wenn das Stände Array nur ein Objekt enthält, wird 0 zurückgegeben.
Und das Array kann nun beliebig wachsen.
-
Vielen herzlichen Dank für die vielen Mühen, die du sicherlich trotz deinem großen Können hast auf dich genommen. Wie ich befürchtet habe: Das Ganze war gleich mehrere Nummern zu groß für einen Anfänger wie mich. Da du jedoch gleich mehrere Lösungen anbietest, habe ich Hoffnung, wenigstens die ein oder andere zu verstehen.
-
@legro Du musst halt fragen, wenn Du was nicht verstehst. Kern ist dieses Mal das nutzen der $reduce Funktion: https://docs.jsonata.org/higher-order-functions#reduce
Diese verwendet man generell, wenn man mehrere Werte in einem Zusammenfassen will.
Sowas kannst Du wenn Du das lieber machst auch in Blockly machen. Ich behaupte nur mal, da brauchst Du 10 mal soviel Code bzw. Puzzleteilchen.
-
@mickym sagte in JSON Objekte in Liste:
@legro Du musst halt fragen, wenn Du was nicht verstehst. Kern ist dieses Mal das nutzen der $reduce Funktion: https://docs.jsonata.org/higher-order-functions#reduce
Die hatte ich mir angeschaut, während ich auf deine Lösungen wartete. Mich überfordert das Ganze noch gewaltig. Allein um weitere Fragen zu stellen, muss ich erst einmal die eine oder andere Grundlage sicher verstanden haben.
Sowas kannst Du wenn Du das lieber machst auch in Blockly machen. Ich behaupte nur mal, da brauchst Du 10 mal soviel Code bzw. Puzzleteilchen.
Da kann ich dir nur zustimmen. Während du hier für mich die Lösung in JSONata erstellt hast, hatte ich parallel dazu versucht, meine Ziele via Blockly zu realisieren. Selbstverständlich stampfe ich dieses Vorhaben ein, verfüge ich doch nun über deine großartige Lösung in JSONata.
Meine nächste Vorhaben ..
- Ich möchte in das jeweils letzte ARRAY-Element den jeweils aktuellen Zählerstand schreiben.
- Ich möchte ein weiteres ARRAY-Element (Zählerstand) an-/einfügen.
Hierzu bietet Blockly erst gar nichts an. Ich denke, dass ich mit den Blöcken ..
.. das realisiert bekomme.
-
@legro na dann musst Du wieder JS programmieren. Wie gesagt ich bin kein Blockly Spezialist, das kann @paul53 viel besser, aber
mit diesem Baustein solltest Du das Array erweitern können.
und wenn Du auf setze änderst, wird das letzte Element geändert
Aber wie gesagt musst ausprobieren. Ich nutze das Tool sonst nicht.
-
@mickym sagte in JSON Objekte in Liste:
Aber wie gesagt musst ausprobieren.
In der Tat.
Ich entnehme das Objekt ja aus einem Datenpunkt, der nach meinem Verständnis ja bloß einen JSON-Text enthält. Schreiben sollte ich jedoch nur auf die Felder des aus diesem Text erzeugten Objektes können. Somit sollte nach den Änderungen das Ganze wieder zurück als Text in den Datenpunkt geschrieben werden.
Mal sehen, ob ich mit dieser Strategie ans Ziel komme.
-
[@mickym sagte in JSON Objekte in Liste:
@legro Du musst halt fragen, wenn Du was nicht verstehst. ..
Dann will ich dich mal beim Wort nehmen.
Während du für mich deine Lösungen zusammengebastelt hast, war ich nämlich nicht untätig.
Nachdem wir ja die Aufgabenstellung zerlegt hatten in ..
- Summe der Produkte (Wert * Energiepreis) und ..
- Summe der Differenzen auf einanderfolgender ARRAY-Elemente, ..
.. versuchte ich aus diesen beiden Gedanken die Lösung zusammenzubasteln. Leider mit viel wenig Erfolg.
In diesem ARRAY galt es nun mittels der ersten Idee die Differenzsummen zu bilden, was mir nicht gelang, weil ich diese deine oben angegebene Lösung hierzu letztendlich wohl nicht tiefgreifend genug verstanden habe.
Die Kodierung $#$i.[$$[$i+1]-$$[$i]] verstehe ich nur teilweise. Hier, was ich glaube, verstanden zu haben ..
- $ steht für einen relativen Pfad. (Am Anfang hätte also auch $$ stehen können.)
- $$ steht für den absoluten (gesamten) Pfad von Beginn an.
- $i steht für eine - nennen wie sie mal - Hilfsvariable (und könnte auch ganz anders heißen).
- Aber was macht der Operator '#' genau? Pappt er (wie auch '@') den Pfad aus $ an die Variable $i und bezeichnet damit in der Ausgabe das ermittelte ARRAY-Element (Differenz).
- [$$[$i+1]-$$[$i]] bildet die Differenz zweier aufeinander folgender Element, die durch die Indizes $i und $i+1 referenziert werden.
Was ich mich frage ..
- Könnte man nicht die beiden Ansätze 1. und 2. zu einer Lösung zusammenfügen? Wenn ja, wie?
- Was mich nach wie vor völlig verwirrt, ist die Tatsache, dass keinerlei Syntax auf eine Kontrollstruktur (hier wird ja wohl eine Schleife erzeugt) zu sehen ist.
- Auch verstehe ich nicht, warum ich nicht in Anlehnung aus deiner Lösung zu 2. in 1. hätte kodieren können [ZählerStände.Bezug[$i].Wert * ZählerStände.Bezug[$i].Wert.Energiepreis]
-
@legro sagte in JSON Objekte in Liste:
[@mickym sagte in JSON Objekte in Liste:
@legro Du musst halt fragen, wenn Du was nicht verstehst. ..
Dann will ich dich mal beim Wort nehmen.
Während du für mich deine Lösungen zusammengebastelt hast, war ich nämlich nicht untätig.
Nun manches kann ich erklären, manches nicht. Manchmal muss ich auch ausprobieren und ich habe auch erst lange gebraucht bis ich es einigermaßen verstanden habe. Manches habe ich aber auch nicht verstanden. Was ich nicht verstehe, warum DU nicht meine endgültige Lösung nimmst, die funktioniert (nämlich die mit der $reduce Funktion). Die lässt Du bei den Fragen hier komplett außen vor.
Grundsätzlich ist es so, dass JSONATA eine mächtige Bibliothek ist, aber kein Compiler und auch kein Interpreter, wie Du ihn bei klassischen Programmiertools findest. Deswegen kannst Du JSONATA in andere Tools einbinden, aber es hat kein Gedächtnis. Deshalb schon mal ein Grundsatz, den Du Dir unbedingt merken musst.
JSONATA arbeitet einfach die Anweisungen von links nach rechts (oder oben nach unten ab) und kann NICHT auf Ergebnisse zurückgreifen oder auf Strukturen zurückgreifen, die sich während der Abarbeitung ergeben. Du hast lediglich den Anker $$, der immer auf das unverfälschte Eingangsobjekt zugreifen kann. $ hingegen enthält immer den aktuellen Kontext, der NICHT fest ist sondern wo Du Dich gerade in einer Objekthierarchie befindest. Das musst Du im Hinterkopf haben und deshalb funktioniert das Kombinieren der beiden Methoden mit komplexen Objekten eben nicht und ich habe auf die $reduce Funktion zurück gegriffen.Nachdem wir ja die Aufgabenstellung zerlegt hatten in ..
- Summe der Produkte (Wert * Energiepreis) und ..
- Summe der Differenzen auf einanderfolgender ARRAY-Elemente, ..
.. versuchte ich aus diesen beiden Gedanken die Lösung zusammenzubasteln. Leider mit viel wenig Erfolg.
Die Differenzsumme mit diesen Mitteln zu erreichen, ist von der Syntax sehr kompliziert, weil Du IMMER den vollständigen Pfad von der Wurzel aus referenzieren musst. Bei dem einfachen Array ging das - deswegen ist die $reduce Funktion wesentlich besser, da Du hier sowohl relativ als auch auf den Dich beziehenden Teil des Arrays Dich beziehen kannst.
In diesem ARRAY galt es nun mittels der ersten Idee die Differenzsummen zu bilden, was mir nicht gelang, weil ich diese deine oben angegebene Lösung hierzu letztendlich wohl nicht tiefgreifend genug verstanden habe.
Das ist eine geniale Möglichkeit von JSONATA, das funktioniert aber nur innerhalb von Objekten, die ein Index gerade durchläuft. DU kannst NICHT auf Elemente vorher und hinterher zurückgreifen, da JSONATA die nicht kennt. Zumindest nicht ohne Dich wieder auf das root-Objekt zu beziehen und nicht im aktuellen Kontext.
Die Kodierung $#$i.[$$[$i+1]-$$[$i]] verstehe ich nur teilweise. Hier, was ich glaube, verstanden zu haben ..
- $ steht für einen relativen Pfad. (Am Anfang hätte also auch $$ stehen können.)
Ja für den aktuellen Kontext. Stimmt am Anfang entspricht $ = $$. Sobald Du aber ein Objekt darunter ansprichst z.Bsp. $.Zählerstände - enthält nun die Variable $ das Array aber nicht mehr das gesamte Objekt wie $$.
- $$ steht für den absoluten (gesamten) Pfad von Beginn an.
Einfach das GESAMTE Objekt oder Array (so wie es im linken Fenster steht)
- $i steht für eine - nennen wie sie mal - Hilfsvariable (und könnte auch ganz anders heißen).
Ja - ich hätte es auch $index nennen können. Alle Variablen in JSONATA beginnen mit einem $
- Aber was macht der Operator '#' genau? Pappt er (wie auch '@') den Pfad aus $ an die Variable $i und bezeichnet damit in der Ausgabe das ermittelte ARRAY-Element (Differenz).
Er weist der darauffolgenden Variable den aktuellen Index, der beim Durchlaufen eines Arrays gebildet wird. Wenn Du Dein Array Zählerstände anschaust, dann hat es genau 3 Elemente, die kannst Du so referenzieren.
https://try.jsonata.org/Car4x9aq9
- [$$[$i+1]-$$[$i]] bildet die Differenz zweier aufeinander folgender Element, die durch die Indizes $i und $i+1 referenziert werden.
Was ich mich frage ..
- Könnte man nicht die beiden Ansätze 1. und 2. zu einer Lösung zusammenfügen? Wenn ja, wie?
Ich habe es mal gemacht und habe den Ansatz 2 aus der Differensumme mit Deinem Objekt berechnet:
https://try.jsonata.org/iqLO5ZyO9[$sum($.ZählerStände.Bezug#$Index.[($$.ZählerStände.Bezug[$Index+1].Wert-$$.ZählerStände.Bezug[$Index].Wert)/1000 * $$.ZählerStände.Bezug[$Index+1].Energiepreis]), $sum($.ZählerStände.Verkauf#$Index.[($$.ZählerStände.Verkauf[$Index+1].Wert-$$.ZählerStände.Verkauf[$Index].Wert)/1000 * $$.ZählerStände.Verkauf[$Index+1].Energiepreis]), $sum($.ZählerStände.Erzeugt#$Index.[($$.ZählerStände.Erzeugt[$Index+1].Wert-$$.ZählerStände.Erzeugt[$Index].Wert)/1000 * $$.ZählerStände.Erzeugt[$Index+1].Energiepreis])]
- Was mich nach wie vor völlig verwirrt, ist die Tatsache, dass keinerlei Syntax auf eine Kontrollstruktur (hier wird ja wohl eine Schleife erzeugt) zu sehen ist.
Das ist das geniale an JSONATA mit dem MAP Operator durchläufst Du automatisch ein Array. Und der Map Operator ist ein "Punkt"
.
https://docs.jsonata.org/path-operators#-map
Also wo Du in anderen Programmiersprachen ein ewiges Konstrukt mit for() und irgendwelchen Schleifen machen musst, langt es in JSONATA hinter einem Array einen Punkt zu machen und es wird durchlaufen. Ist ja an diesem Beispiel schön zu sehen:
- Auch verstehe ich nicht, warum ich nicht in Anlehnung aus deiner Lösung zu 2. in 1. hätte kodieren können [ZählerStände.Bezug[$i].Wert * ZählerStände.Bezug[$i].Wert.Energiepreis]
Wie gesagt ich hab es Dir ja nach der 2. Methode nun codiert, obwohl die $reduce Funktion einfacher ist, zumindest wenn Du die Objekte benennst, wie hier: https://try.jsonata.org/1lDqzoiKc
So streng genommen um Lösung 1 und 2 kombinieren - muss man halt statt der eckigen runde Klammern verwenden:
[$sum($.ZählerStände.Bezug#$Index.(($$.ZählerStände.Bezug[$Index+1].Wert-$$.ZählerStände.Bezug[$Index].Wert)/1000 * $$.ZählerStände.Bezug[$Index+1].Energiepreis)), $sum($.ZählerStände.Verkauf#$Index.(($$.ZählerStände.Verkauf[$Index+1].Wert-$$.ZählerStände.Verkauf[$Index].Wert)/1000 * $$.ZählerStände.Verkauf[$Index+1].Energiepreis)), $sum($.ZählerStände.Erzeugt#$Index.(($$.ZählerStände.Erzeugt[$Index+1].Wert-$$.ZählerStände.Erzeugt[$Index].Wert)/1000 * $$.ZählerStände.Erzeugt[$Index+1].Energiepreis))]
https://try.jsonata.org/O15UAuwUB
Im Prinzip kann man bei der 2. Methode auch runde Klammern verwenden. So sind 1 und 2 kombiniert. Manchmal liegts bei mir auch am Probieren, bis ich es verstehe.
$#$i.($$[$i+1]-$$[$i])
funktioniert also genauso und ist im Prinzip - Methode 1 nur mit jeweiligem Bezug zum Root-Objekt
Schau Dir bitte alle Beispiele und Links an, sonst wirst Du es nicht verstehen - hoffe nun aber Klarheit in die Sache gebraucht zu haben und habe nun nach der 2. Methode (Differenzsumme) auch Deine Werte kalkuliert.