mein erstes node object
der henry
- javascript
- node
Hallo,
ich möchte ein object erstellen
So sollte es aussehen ...
datenpunktliste.plcname.plcvarname
datenpunktliste.plcname.type
datenpunktliste.plcname.db
Als Beispiel lese ich aus einem Object mit Namen "zeile"
Ich komme aber mit der Verschachtelung/Klammern nicht zurecht .. mein Ansatz ...
Object.assign(datenpunktliste, {"plcname": act_plcname};
// hier käme dann eine Schleife ....
Object.assign(datenpunktliste, {"spsname":
[
{
"plcvarname": zeile.spsvarname,
"type": zeile.datentyp,
"db": zeile.db
}
]};
Der Zugriff wäre dann ??
let mytype = datenpunktliste.M1.type;
Vielen Dank
greenhorn
Hallo Henry,
ich kann Dir nur ansatzweise folgen. Mir scheint, mit plcname
meinst Du einen beliebigen Schlüsselbegriff, wie z.B. "M1".
Diese Anweisung
Object.assign(datenpunktliste, {"plcname": act_plcname});
erzeugt aber in datenpunktliste
lediglich eine Eigenschaft namens plcname
und speichert darin den Wert von act_plcname. Genausogut könntest Du
datenpunktliste.plcname = act_plcname;
schreiben. Object.assign kopiert einfach die enumerierbaren Eigenschaften eines Objekts in ein anderes.
Wenn Du eine Eigenschaft erzeugen möchtest, deren Name in act_plcname steht, musst Du die Notation mit eckigen Klammern verwenden:
datenpunktliste[act_plcname] = ...;
Und in Datenpunktliste möchtest Du unter unterschiedlichen Schlüsseln (also act_plcname-Werte) dann Informationsobjekte zu diesem plcname hinterlegen? Wie kommst Du im Schleifendurchlauf an diese Werte heran? Das zeigt dein Code nicht.
Und eventuell ist ein Objekt auch gar nicht die richtige Lösung für Dich. Die Datenstruktur, die Du hier zu planen scheinst, ist eine Map. Und dafür gibt's in JavaScript die Map-Klasse. Der Wiki-Artikel steigt etwas abstrakt ein, lies einfach, er enthält einige Beispiele.
datenstrukturliste = new Map();
datenstrukturliste.set(act_plcname, { plcvarname: zeile.spsvarname,
type: zeile.datentyp,
db: zeile.db });
plcdaten = datenstrukturliste.get("M1");
alleKeys = Array.from(datenstrukturliste.keys());
Früher gab es diese Klasse nicht und man hat Objekte als Maps missbraucht. Aber Node.js sollte Maps kennen.
Rolf
Hallo Rolf,
ich möchte meine Daten nochmals, aber detaillierter erklären.
Ich hole mir die Daten aus einer mysql Datenbank. Hier bekomme ich ein Array mit Objekten zurück.
Um im laufendem Programm gezielter und einfacher auf die Daten zugreifen zu können, ohne jeweils eine Schleife benützen zu müssen, möchte ich die Daten "anders" abspeichern bzw. einmalig umkopieren.
Maschinenname: M1
plcvarname: Drehzahl
format: double
offset: 120
.. usw
plcvarname: Temperatur
format: double
offset: 128
.. usw
usw.
Maschinenname: M2
plcvarname: Drehzahl
format: double
offset: 220
.. usw
plcvarname: Temperatur
format: double
offset: 228
.. usw
usw.
Alle Daten in einem "Speicher"
Daher dachte ich an ein verschalteltes object
Lesen der Daten z.B. ... (eventuell klammern bzw. anders formatieren)
let x = datenpunktliste.M1.Drehzahl.format
oder
let y = datenpunktliste.M2.Drehzahl.offeset
Eventuell liege ich falsch und so etwas geht gar nicht 😉 Bin für jeden Tip dankbar !!
Gruß
Moin Henry,
ich habe in Deiner Antwort den Code entsprechend ausgezeichnet, damit er lesbarer ist. Das kannst Du ab jetzt dann auch selbst 😉
Viele Grüße
Robert
Moin Henry,
Maschinenname: M1 plcvarname: Drehzahl format: double offset: 120 .. usw plcvarname: Temperatur format: double offset: 128 .. usw usw. Maschinenname: M2 plcvarname: Drehzahl format: double offset: 220 .. usw plcvarname: Temperatur format: double offset: 228 .. usw usw.
Lesen der Daten z.B. ... (eventuell klammern bzw. anders formatieren)
let x = datenpunktliste.M1.Drehzahl.format
oder
let y = datenpunktliste.M2.Drehzahl.offeset
das entsprechende Objekt sähe in etwa so aus:
const datenpunktliste = {
M1: {
Drehzahl: {
format: 'double',
offset: 120,
// …
},
Temperatur: {
format: 'double',
offset: 128,
// …
}
},
M2: {
Drehzahl: {
format: 'double',
offset: 220,
// …
},
Temperatur: {
format: 'double',
offset: 228,
// …
}
}
};
Offensichtlich sind M1 und M2 vom gleichen Objekt-Typ („Maschine“) und beinhalten die gleichen Objekttypen (physikalische Einheiten), d.h. es sind Abkürzungen möglich:
function Einheit(format, offset, /* … */) {
this.format = format;
this.offset = offset;
// …
}
function Maschine(drehzahl, temperatur, /* … */) {
this.Drehzahl = new Einheit('double', drehzahl, /* … */);
this.Temperatur = new Einheit('double', temperatur, /* … */);
}
const datenpunktliste = {
M1: new Maschine(120, 128, /* … */),
M2: new Maschine(220, 228, /* … */)
}
Viele Grüße
Robert
Hallo Robert,
vielen Dank für deine Unterstützung.
Du gibst in deinem Beispiel den plcvarnamen fest vor. Das ist aber nicht so, dieser kann unterschiedlich sein, deshalb habe ich den key "plcvarnamen" benutzt. Auch das format z.B. ist nicht immer "double"
Maschinenname: M1
plcvarname: Drehzahl
format: double
offset: 120
.. usw
plcvarname: Temperatur
format: double
offset: 128
.. usw
Es müsste so aussehen ... Klammer und Komma -Setzung eventuel falsch
const datenpunktliste = {
maschinenname: M1 {
plcvarname: Drehzahl {
format: 'double',
offset: 120,
},
plcvarname: Temperatur {
format: 'integer',
offset: 128,
},
plcvarname: Oeffnung {
format: 'dword',
offset: 132,
}
},
maschinenname: M2 {
plcvarname: Drehzahl {
format: 'double',
offset: 220,
},
plcvarname: Temp_1 {
format: 'integer',
offset: 228,
},
plcvarname: Temp_2 {
format: 'dword',
offset: 232,
}
},
};
PS: Die einzelnen Maschinen (Maschinenname) können die gleichen "plcvarnamen" haben, müssen aber nicht.
Wie kann ich diese Struktur mittels Programm erzeugen ... man gehe von einem leeren objekt, in diesem Fall "datenpunktliste" aus ?
Vielen Dank
Hallo Henry,
das kommt davon, wenn man sein Problem nicht anständig beschreibt, sondern davon ausgeht, dass fremde Menschen die eigene Problemdomäne eh kennen. Die Leute machen dann irgendwelche Annahmen und liegen automatisch falsch. Deshalb auch meine Rückfrage von 11:06 Uhr.
Wir brauchen eine exakte Beschreibung der Eingabedaten und eine exakte Vorgabe, wie die Ausgabe aussehen soll. Andernfalls raten wir nur rum.
Es müsste so aussehen ... Klammer und Komma -Setzung eventuel falsch...
Nicht nur die. Das ist kein JavaScript, sondern Phantasiesyntax. Wie es Javascript-mäßiger aussehen könnte, zeige ich gleich. Der erläuternde Wiki-Artikel ist Objekte und ihre Eigenschaften.
Ich versuche mal einen Schritt in eine möglicherweise richtige Richtung. Deine Eingabedaten sind ein Array aus Objekten mit den Schlüsseln Maschinenname, plcvarname, format, offset und noch ein paar mehr? Mit Array- und Objektliteralen in JavaScript könnte man das so aufschreiben:
eingabe = [
{ Maschinenname: "M1", plcvarname: "Drehzahl", format: "double", offset: 220, dings: 17, bums: 99 },
{ Maschinenname: "M1", plcvarname: "Temperatur", format: "integer", offset: 128, dings: 11, bums: 77 },
{ Maschinenname: "M1", plcvarname: "Oeffnung", format: "dword", offset: 132, dings: 13, bums: 47 },
{ Maschinenname: "M2", plcvarname: "Drehzahl", format: "double", offset: 220, dings: 17, bums: 99 },
{ Maschinenname: "M2", plcvarname: "Temp_1", format: "integer", offset: 128, dings: 11, bums: 77 },
{ Maschinenname: "M2", plcvarname: "Temp_2", format: "integer", offset: 132, dings: 13, bums: 47 }
];
Soweit richtig geraten?
Entstehen soll daraus ein Objekt, das als Literal geschrieben so aussähe?
datenpunktliste = {
M1: {
Drehzahl: { format: "integer", offset: 220, dings: 17, bums: 99 },
Temperatur: { format: "integer", offset: 128, dings: 11, bums: 77 },
Oeffnung: { format: "dword", offset: 132, dings: 13, bums: 47 },
},
M2: {
Drehzahl: { format: "integer", offset: 220, dings: 17, bums: 99 },
Temp_1: { format: "integer", offset: 128, dings: 11, bums: 77 },
Temp_2: { format: "integer", offset: 132, dings: 13, bums: 47 },
},
};
Ist das richtig?
Die Eigenschaftsnamen "M1", "M2", "Drehzahl", "Temperatur" und so weiter sind dabei ein Risiko. Wenn deine DB-Abfrage einen Maschinennamen wie "Nummer 5" oder "NGC-1701" liefert, ist das KEIN gültiger Name. Objekteigenschaften mit solchen Namen sind zwar zulässig, sind aber nicht über die Punkt-Schreibweise erreichbar. In einem Objektliteral müssen sie dann in Anführungszeichen stehen, und beim Zugriff auf die Eigenschaft brauchst Du die Index-Notation. Steht alles im Abschnitt "Eigenschaften mit irregulären Namen" im verlinkten Wiki-Artikel.
Beim Erstellen von Eigenschaften mit variablen Namen brauchst Du eh die Index-Notation.
Rolf
Hallo,
eingabe = [ { Maschinenname: "M1", plcvarname: "Drehzahl", format: "double", offset: 220, dings: 17, bums: 99 }, { Maschinenname: "M1", plcvarname: "Temperatur", format: "integer", offset: 128, dings: 11, bums: 77 }, { Maschinenname: "M1", plcvarname: "Oeffnung", format: "dword", offset: 132, dings: 13, bums: 47 }, { Maschinenname: "M2", plcvarname: "Drehzahl", format: "double", offset: 220, dings: 17, bums: 99 }, { Maschinenname: "M2", plcvarname: "Temp_1", format: "integer", offset: 128, dings: 11, bums: 77 }, { Maschinenname: "M2", plcvarname: "Temp_2", format: "integer", offset: 132, dings: 13, bums: 47 } ];
Soweit richtig geraten?
Ja, das ist richtig
datenpunktliste = { M1: { Drehzahl: { format: "integer", offset: 220, dings: 17, bums: 99 }, Temperatur: { format: "integer", offset: 128, dings: 11, bums: 77 }, Oeffnung: { format: "dword", offset: 132, dings: 13, bums: 47 }, }, M2: { Drehzahl: { format: "integer", offset: 220, dings: 17, bums: 99 }, Temp_1: { format: "integer", offset: 128, dings: 11, bums: 77 }, Temp_2: { format: "integer", offset: 132, dings: 13, bums: 47 }, }, };
Ist das richtig?
Ja richtig, damit kann ich gut leben !! Ich möchte jetzt in einer Schleife das Objekt füllen. Dazu habe ich nachfolgenden Code
result.forEach(function (zeile) {
sps_datenpunktliste = {
[aktiver_spsname]: {
[zeile.spsvarname]: {
datentyp: zeile.datentyp, db: zeile.db, offset: zeile.offset, bit: zeile.bit, format: zeile.format, nachkomma: zeile.nachkomma
}
}
}
});
Dies funktioniert in so weit, das jede Zeile im Objekt überschrieben wird, was ich auch verstehe, da das Objekt komplett neu beschrieben wird.
Trotz intensiver suche im Netz habe ich nichts passendes zum Thema "dynamische beschreiben verschachtelter Objekte" gefunden. 😉
Mein Ansatz wäre nun gewesen
result.forEach(function (zeile) {
sps_datenpunktliste = aktiver_spsname;
sps_datenpunktliste[aktiver_spsname] = zeile.spsvarname;
sps_datenpunktliste[aktiver_spsname][zeile.spsvarname] = {
datentyp: zeile.datentyp, db: zeile.db, offset: zeile.offset, bit: zeile.bit, format: zeile.format, nachkomma: zeile.nachkomma }
});
Ich kann den Key "aktiver_spsname" beschreiben ... soweit funktioniert es. Dann müsste ich eigentlich eine Stufe tiefer kommen und "zeile.spsvarname" beschreiben können ... Pustekuchen ...
Hier komm ich nicht weiter ...
Moin Henry,
Ich möchte jetzt in einer Schleife das Objekt füllen. Dazu habe ich nachfolgenden Code
result.forEach(function (zeile) { sps_datenpunktliste = { [aktiver_spsname]: { [zeile.spsvarname]: { datentyp: zeile.datentyp, db: zeile.db, offset: zeile.offset, bit: zeile.bit, format: zeile.format, nachkomma: zeile.nachkomma } } } });
Vielleicht möchtest Du dich noch einmal genauer mit der JavaScript-Syntax auseinandersetzen. Wir haben ein ganzes Wiki dazu. Kurz beschrieben macht Dein Code folgendes:
In jedem Schleifendurchlauf wird ein Objekt sps_datenpunktliste
angelegt, das seine Attributnamen aus den Variablen aktiver_spsname
und zeile.spsvarname
nimmt. Erstere Variable scheint dabei global und konstant für jede Zeile zu sein.
Dies funktioniert in so weit, das jede Zeile im Objekt überschrieben wird, was ich auch verstehe, da das Objekt komplett neu beschrieben wird.
Trotz intensiver suche im Netz habe ich nichts passendes zum Thema "dynamische beschreiben verschachtelter Objekte" gefunden. 😉
Vielleicht liegt es daran, dass Dein Suchbegriff kein Fachbegriff (in JavaScript) ist und nicht im Entferntesten beschreibt, was Du vermutlich eigentlich tun möchtest: Objekte um Eigenschaften erweitern. Es ist ja nicht so, als hätte das Rolf bereits in seiner ersten Antwort beschrieben …
Mein Ansatz wäre nun gewesen
result.forEach(function (zeile) { sps_datenpunktliste = aktiver_spsname; sps_datenpunktliste[aktiver_spsname] = zeile.spsvarname; sps_datenpunktliste[aktiver_spsname][zeile.spsvarname] = { datentyp: zeile.datentyp, db: zeile.db, offset: zeile.offset, bit: zeile.bit, format: zeile.format, nachkomma: zeile.nachkomma } });
Ich kann den Key "aktiver_spsname" beschreiben ... soweit funktioniert es. Dann müsste ich eigentlich eine Stufe tiefer kommen und "zeile.spsvarname" beschreiben können ... Pustekuchen ...
Dein Code macht folgendes:
sps_datenpunktliste
neu als String an.aktiver_spsname
steht und weise diesem den String aus zeile.spsvarname
zu.zeile.spsvarname
und weise diesem ein neues Objekt zu.Ich könnte mir vorstellen, dass das Weglassen der ersten beiden Code-Zeilen in der Schleife und entsprechend korrektes Initialisieren von sps_datenpunktliste
bereits ausreicht um dort hin zu kommen, wo Du eigentlich hinmöchtest.
Viele Grüße
Robert
Hallo Robert,
- Lege das Objekt sps_datenpunktliste neu als String an.
- Erweitere den String um das Attribut mit dem Namen, der in aktiver_spsname steht und weise diesem den String aus zeile.spsvarname zu.
Das ist eine beliebte Falle, in die man bei JavaScript tappen kann. Ein String ist ein primitiver Typ, kein Objekt.
let a = "Hallo";
console.log(typeof a);
// "string"
Da müsste "object" stehen, wenn a ein Objekt wäre. Verwendet man einen primitiven Typ wie ein Objekt, findet etwas statt, was in anderen Sprachen "boxing" genannt wird: der primitive Wert wird in ein Objekt eingekapselt. In diesem Fall: String (großes s). Auf diesem Objekt wird die objektorientierte Aktion ausgeführt, danach wird das Objekt wieder entfernt.
Dieser Code
let a = "Hallo";
a.who = "Welt";
console.log(a.who);
weist dem String "Hallo" keine Eigenschaft who zu. Das wäre fatal, weil Strings unveränderlich sind und von der JS Engine internalisiert werden (heißt: Steht dreimal "Hallo" im Code, gibt's diesen String tatsächlich nur einmal. Würde man ihm Eigenschaften zuweisen können, würde sich diese Änderung auf jede Stelle auswirken, wo "Hallo" irgendwohin zugewiesen wird).
Was in Wahrheit passiert, ist:
let a = "Hallo";
const __tempString = new String(a);
__tempString.who = "Welt";
console.log(a.who); // undefined
Und ja, das passiert auch beim Anwenden von Stringmethoden!
let a = "Hallo";
console.log(a.substring(0,1) + a.substring(4,5)); // "Ho"
ist in Wahrheit
let a = "Hallo";
const __tempString1 = new String(a);
const __tempResult1 = __tempString1.substring(0,1);
const __tempString2 = new String(a);
const __tempResult2 = __tempString2.substring(4,5);
console.log(__tempResult1 + __tempResult2);
Wobei eine ordentliche JS-Engine erkennen sollte, dass sie hier mit einem Temp-String auskommt. Andererseits kann so eine Optimierung auch gefährlich enden, die Engine muss also SEHR gut sein, um Fälle wie diesen hier richtig zu behandeln:
// Nicht nachmachen!
let a = "Hallo";
function setA(val) {
a = val;
return "*";
}
console.log(a.substring(0,1)+setA("Wonka")+a.substring(4,5));
Welches Ergebnis würdest Du erwarten? "H*o"
oder "H*a"
?
Rolf
Hallo Henry,
sicher geht das. Du hast es aber wieder geschafft, mich zu verwirren.
Dein "Array"-Beispiel ist hierarchisch dargestellt. Ist das bei Dir so? Wenn ja, dann schreib es doch bitte als Objektliteral auf, damit man die Struktur richtig erkennt.
Oder ist das Array flach, und die Spalten für Maschinenname und plcvarname wiederholen sich für jedes Datenelement? So, wie es mysqli in PHP als Resultset liefert? Wie heißen die Spalten exakt?
Rolf