Ich habe eine Datenstruktur wie diese:
var someObject = {
'part1' : {
'name': 'Part 1',
'size': '20',
'qty' : '50'
},
'part2' : {
'name': 'Part 2',
'size': '15',
'qty' : '60'
},
'part3' : [
{
'name': 'Part 3A',
'size': '10',
'qty' : '20'
}, {
'name': 'Part 3B',
'size': '5',
'qty' : '20'
}, {
'name': 'Part 3C',
'size': '7.5',
'qty' : '20'
}
]
};
Und ich möchte mit dieser Variablen auf die Daten zugreifen:
var part1name = "part1.name";
var part2quantity = "part2.qty";
var part3name1 = "part3[0].name";
part1name sollte mit someObject.part1.name
dem Wert "Part 1" gefüllt werden . Gleiches gilt für part2quantity, das mit 60 gefüllt ist.
Gibt es überhaupt eine Möglichkeit, dies mit reinem Javascript oder JQuery zu erreichen?
javascript
jquery
path
nested
Komaruloh
quelle
quelle
var part1name = someObject.part1name;
`Antworten:
Ich habe dies nur basierend auf einem ähnlichen Code gemacht, den ich bereits hatte. Es scheint zu funktionieren:
Verwendungszweck::
Eine funktionierende Demo finden Sie unter http://jsfiddle.net/alnitak/hEsys/.
BEARBEITEN Einige haben festgestellt, dass dieser Code einen Fehler auslöst, wenn eine Zeichenfolge übergeben wird, bei der die am weitesten links stehenden Indizes keinem korrekt verschachtelten Eintrag im Objekt entsprechen. Dies ist ein berechtigtes Anliegen, aber IMHO wird
try / catch
beim Aufrufen am besten mit einem Block angesprochen , anstatt diese Funktion stillschweigendundefined
für einen ungültigen Index zurückgeben zu lassen.quelle
_.get(object, nestedPropertyString);
'part3[0].name.iDontExist'
. Durch Hinzufügen einer Überprüfung, obo
ein Objekt in derif in
Datei enthalten ist, wird das Problem behoben. (Wie Sie das machen, liegt bei Ihnen). Siehe aktualisierte Geige: jsfiddle.net/hEsys/418Dies ist die Lösung, die ich benutze:
Anwendungsbeispiel:
Einschränkungen:
[]
) können nicht für Array-Indizes verwendet werden. Die Angabe von Array-Indizes zwischen dem Trennzeichen (z. B..
) funktioniert jedoch wie oben gezeigt.quelle
_.reduce()
von Reduce ist eine hervorragende Lösung (man kann sie auch aus der Unterstrich- oder Lodash-Bibliothek verwenden)self
ist hier wahrscheinlich undefiniert. Meinst duthis
?Dies wird jetzt von lodash using unterstützt
_.get(obj, property)
. Siehe https://lodash.com/docs#getBeispiel aus den Dokumenten:
quelle
_.set(...)
_.get
dasselbe Verhalten wie wenn im angegebenen Objekt kein Schlüssel gefunden wird. zB_.get(null, "foo") -> undefined
,_.get(null, "foo", "bar") -> "bar"
. Dieses Verhalten ist jedoch in den Dokumenten nicht definiert und kann sich daher ändern.ES6 : Nur eine Zeile in Vanila JS (sie gibt null zurück, wenn sie nicht gefunden wird, anstatt einen Fehler zu geben):
Oder Beispiel:
Für eine gebrauchsfertige Funktion, die auch falsche, 0 und negative Zahlen erkennt und Standardwerte als Parameter akzeptiert:
Zu verwendendes Beispiel:
Bonus :
Um setzen einen Pfad (Angefordert von @ rob-gordon) können Sie verwenden:
Beispiel:
Zugriff auf Array mit [] :
Beispiel:
quelle
let o = {a:{b:{c:1}}}; let str = 'a.b.c'; str.split('.').splice(0, str.split('.').length - 1).reduce((p,c)=>p&&p[c]||null, o)[str.split('.').slice(-1)] = "some new value";
0
,undefined
undnull
Werte.{a:{b:{c:0}}}
kehrtnull
statt statt0
. Möglicherweise werden diese Probleme durch explizites Überprüfen auf null oder undefiniert behoben.(p,c)=>p === undefined || p === null ? undefined : p[c]
Reflect.has(o, k) ? ...
(ES6 Reflect.has ) funktioniert hatsetPath
setzt den Wert beim ersten Auftreten des letzten Selektors. Zum Beispiellet o = {}; setPath(o, 'a.a', 0)
führt{a: 0}
eher zu als{a: {a: 0}}
. In diesem Beitrag finden Sie eine Lösung.Sie müssten die Zeichenfolge selbst analysieren:
Dazu müssen Sie auch Array-Indizes mit Punktnotation definieren:
Dies erleichtert das Parsen.
DEMO
quelle
[]
Syntax in Eigenschaftssyntax ist ziemlich trivial.while (l > 0 && (obj = obj[current]) && i < l)
funktioniert dieser Code auch für Zeichenfolgen ohne Punkte.Funktioniert auch für Arrays / Arrays innerhalb des Objekts. Defensiv gegen ungültige Werte.
quelle
mit eval:
Wrap, um bei einem Fehler undefiniert zurückzugeben
http://jsfiddle.net/shanimal/b3xTw/
Bitte seien Sie mit gesundem Menschenverstand und Vorsicht, wenn Sie die Macht der Bewertung ausüben. Es ist ein bisschen wie ein Lichtschwert. Wenn Sie es einschalten, besteht eine Wahrscheinlichkeit von 90%, dass Sie sich ein Glied abtrennen. Es ist nicht jedermanns Sache.
quelle
Mit dem folgenden einfachen Trick können Sie den Wert eines Deep-Object-Elements mit Punktnotation ohne externe JavaScript-Bibliothek ermitteln:
In Ihrem Fall, um den Wert
part1.name
vonsomeObject
einfach zu erhalten, tun Sie Folgendes:Hier ist eine einfache Geigen-Demo: https://jsfiddle.net/harishanchu/oq5esowf/
quelle
Dies wird wahrscheinlich nie das Licht der Welt erblicken ... aber hier ist es trotzdem.
[]
Klammernsyntax durch.
.
Zeichenundefined
)quelle
Es ist ein Einzeiler mit Lodash.
Oder noch besser ...
Oder ES6-Version mit ...
Plunkr
quelle
Ich denke, Sie fragen danach:
Sie könnten danach fragen:
Beides wird funktionieren
Oder vielleicht fragen Sie danach
Schließlich könnten Sie danach fragen
quelle
Split
Methode, sondernsplit
.Hier biete ich mehr Möglichkeiten an, die in vielerlei Hinsicht schneller erscheinen:
Option 1: String aufteilen. oder [oder] oder 'oder ", kehren Sie es um, überspringen Sie leere Elemente.
Option 2 (außer am schnellsten
eval
): Niedriger Zeichenscan (kein Regex / Split / etc, nur ein schneller Char-Scan). Hinweis: Dieser unterstützt keine Anführungszeichen für Indizes.Option 3: ( neu : Option 2 erweitert, um Anführungszeichen zu unterstützen - etwas langsamer, aber immer noch schnell)
JSPerf: http://jsperf.com/ways-to-dereference-a-delimited-property-string/3
"eval (...)" ist immer noch König (was die Leistung betrifft). Wenn Sie Eigenschaftspfade direkt unter Ihrer Kontrolle haben, sollte es keine Probleme mit der Verwendung von 'eval' geben (insbesondere wenn Geschwindigkeit gewünscht wird). Wenn Sie Eigenschaftspfade "über den Draht" ziehen ( auf der Linie !? Lol: P), verwenden Sie aus Sicherheitsgründen etwas anderes. Nur ein Idiot würde sagen, dass er "eval" niemals verwenden soll, da es gute Gründe gibt, es zu verwenden. Außerdem "wird es im JSON-Parser von Doug Crockford verwendet ." Wenn die Eingabe sicher ist, gibt es überhaupt keine Probleme. Verwenden Sie das richtige Werkzeug für den richtigen Job, das war's.
quelle
Für den Fall, dass jemand diese Frage 2017 oder später besucht und nach einer leicht zu merkenden Möglichkeit sucht , finden Sie hier einen ausführlichen Blog-Beitrag zum Zugriff auf verschachtelte Objekte in JavaScript ohne von ihm verwirrt zu werden
Die Eigenschaft 'foo' von undefined kann nicht gelesen werden Fehlers werden
Greifen Sie mit Array Reduce auf verschachtelte Objekte zu
Nehmen wir diese Beispielstruktur
Um auf verschachtelte Arrays zugreifen zu können, können Sie Ihr eigenes Array schreiben.
Es gibt auch eine ausgezeichnete Schrift, die minimale Bibliotheksfehler verarbeitet , der all dies für Sie erledigt.
Mit typy sieht Ihr Code folgendermaßen aus
Haftungsausschluss: Ich bin der Autor dieses Pakets.
quelle
AngularJS
Speiggs Ansatz ist sehr ordentlich und sauber, obwohl ich diese Antwort gefunden habe, als ich nach der Lösung gesucht habe, auf AngularJS $ scope-Eigenschaften über einen Zeichenfolgenpfad zuzugreifen, und mit einer kleinen Änderung die Aufgabe erfüllt:
Platzieren Sie diese Funktion einfach in Ihrem Root-Controller und verwenden Sie einen beliebigen untergeordneten Bereich wie folgt:
quelle
$scope.$eval
eine andere Möglichkeit, dies mit AngularJS zu tun.Ich habe noch kein Paket gefunden, um alle Operationen mit einem Zeichenfolgenpfad auszuführen. Daher habe ich mein eigenes schnelles kleines Paket geschrieben, das insert (), get () (mit Standardrückgabe), set () und remove ( ) Operationen.
Sie können Punktnotation, Klammern, Zahlenindizes, Eigenschaften von Zeichenfolgenummern und Schlüssel mit Nicht-Wort-Zeichen verwenden. Einfache Verwendung unten:
https://www.npmjs.com/package/jsocrud
https://github.com/vertical-knowledge/jsocrud
quelle
Arbeitet mit
quelle
Einfache Funktion, die entweder einen String- oder einen Array-Pfad zulässt.
ODER
quelle
Hierfür gibt es
npm
jetzt ein Modul: https://github.com/erictrinh/safe-accessAnwendungsbeispiel:
quelle
Obwohl Reduzieren gut ist, bin ich überrascht, dass niemand für jedes verwendet hat:
Prüfung
quelle
a.b.c
eine Ausnahme aus, wennb
Ihr Objekt keine Eigenschaft enthält . Wenn Sie etwas brauchen, das den falschen Schlüsselpfad stillschweigend abweist (was ich nicht empfehle), können Sie den forEach trotzdem durch diesen ersetzenkeys.forEach((key)=> obj = (obj||{})[key]);
Hatte gerade die gleiche Frage vor kurzem und erfolgreich verwendet https://npmjs.org/package/tea-properties, die auch
set
Objekt / Arrays verschachtelt:erhalten:
einstellen:
quelle
Inspiriert von der Antwort von @ webjay: https://stackoverflow.com/a/46008856/4110122
Ich habe diese Funktion erstellt, mit der Sie einen beliebigen Wert im Objekt abrufen / setzen / deaktivieren können
Um es zu benutzen:
quelle
Ich entwickle einen Online-Shop mit React. Ich habe versucht, die Werte im kopierten Statusobjekt zu ändern, um den ursprünglichen Status beim Senden zu aktualisieren. Die obigen Beispiele haben bei mir nicht funktioniert, da die meisten von ihnen die Struktur des kopierten Objekts mutieren. Ich habe ein funktionierendes Beispiel für die Funktion zum Zugreifen auf und Ändern von Werten der tief verschachtelten Objekteigenschaften gefunden: https://lowrey.me/create-an-object-by-path-in-javascript-2/ Hier ist es:
quelle
Basierend auf Alnitaks Antwort .
Ich wickelte die Polyfüllung in einen Scheck ein und reduzierte die Funktion auf eine einzelne verkettete Reduktion.
quelle
Wenn Sie auf verschiedene verschachtelte Schlüssel zugreifen müssen, ohne diese zum Zeitpunkt der Codierung zu kennen (es ist trivial, sie zu adressieren), können Sie den Array-Notations-Accessor verwenden:
Sie entsprechen dem Punktnotations-Accessor und können zur Laufzeit variieren, zum Beispiel:
ist äquivalent zu
oder
Ich hoffe das adressiert deine Frage ...
BEARBEITEN
Ich werde keine Zeichenfolge verwenden, um eine Art xpath- Abfrage für den Zugriff auf einen Objektwert zu verwalten. Da Sie eine Funktion aufrufen müssen, um die Abfrage zu analysieren und den Wert abzurufen, würde ich einem anderen Pfad folgen (nicht:
oder, wenn Sie mit der Apply- Methode nicht zufrieden sind
Die Funktionen sind kürzer, klarer, der Interpreter überprüft sie für Sie auf Syntaxfehler und so weiter.
Übrigens denke ich, dass eine einfache Aufgabe, die zum richtigen Zeitpunkt gemacht wird, ausreichen wird ...
quelle
Die Lösungen hier sind nur für den Zugriff auf die tief verschachtelten Schlüssel. Ich brauchte einen, um auf die Schlüssel zuzugreifen, sie hinzuzufügen, zu ändern und zu löschen. Das habe ich mir ausgedacht:
path_to_key
: Pfad in einem Array. Sie können es durch Ihr ersetzenstring_path.split(".")
.type_of_function
: 0 für den Zugriff (geben Sie keinen Wert anvalue
), 0 für das Hinzufügen und Ändern. 1 zum Löschen.quelle
Aufbauend auf Alnitaks Antwort:
}}
Damit können Sie auch einen Wert einstellen!
Ich habe ein erstellt npm Paket und Github mit diesem als auch
quelle
Anstelle einer Zeichenfolge kann ein Array verwendet werden, um verschachtelte Objekte und Arrays zu adressieren, z.
["my_field", "another_field", 0, "last_field", 10]
Hier ist ein Beispiel, das ein Feld basierend auf dieser Array-Darstellung ändern würde. Ich verwende so etwas in react.js für kontrollierte Eingabefelder, die den Status verschachtelter Strukturen ändern.
quelle
Basierend auf einer früheren Antwort habe ich eine Funktion erstellt, die auch Klammern verarbeiten kann. Aber keine Punkte in ihnen aufgrund der Spaltung.
quelle
quelle
Arbeiten mit
Underscore
'sproperty
oderpropertyOf
:Viel Glück...
quelle