2017-02-13 3 views
2

Ich bin neu in Java-Skript, so entschuldigen Sie bitte, wenn dies trivial ist. Meine Frage ist syntaktische, wenn ich ein Objekt haben:Abrufen eines Feldes von einem JSON-Objekt mit einem "Adress-String" in JavaScript

this.state = { 
    A : { 
     B: { 
      C : [ 
      {value : 'bob'}, 
      {value : 'Jim'}, 
      {value : 'luke'}, 
      ] 
     } 
    } 
} 

und ich habe eine Zeichenfolge location = 'A.B.C[1]', die den Ort der Daten beschreiben ich will.

Warum kann ich nicht einfach data = this.state[location].value?

und gibt es einen einfachen "JavaScript" Weg, um die Daten mit dem Ort String zu bekommen?

jede Hilfe wäre erstaunlich :)

+0

Es gibt kein integriertes Tool dafür. Ein Begriff, den ich für dieses Problem verwendet habe, ist "Objekt Graph Navigation". Es gibt mindestens eine gute doppelte Frage auf der Website, aber es ist schwer zu finden. – Pointy

+0

Wie wird die Zeichenfolge generiert? Dies könnte ein XY-Problem sein – charlietfl

+0

Verwenden Sie eine Regex auf Ihrem Standort, um alle Ebenen zu bekommen – Weedoze

Antwort

5

Sie können den Pfad aufgespalten und das Objekt zu reduzieren.

function getValue(o, path) { 
 
    return path.replace(/\[/g, '.').replace(/\]/g, '').split('.').reduce(function (o, k) { 
 
     return (o || {})[k]; 
 
    }, o); 
 
} 
 

 
var o = { A : { B: { C: [{ value: 'Brenda' }, { value: 'Jim' }, { value: 'Lucy' }] } }}; 
 

 
console.log(getValue(o, 'A.B.C[1]').value); // Jim 
 
console.log(getValue(o, 'A.B.C[0].value')); // Brenda 
 
console.log(getValue(o, 'Z[0].Y.X[42]')); // undefined

Für einen Wert einstellen, können Sie den Pfad aufgespalten und den Pfad zu reduzieren, indem das entsprechende Objekt zu Fuß. Wenn kein Objekt vorhanden ist, erstellen Sie eine neue Eigenschaft mit dem Namen oder einem Array. Weisen Sie später den Wert zu.

function setValue(object, path, value) { 
 
    var way = path.replace(/\[/g, '.').replace(/\]/g, '').split('.'), 
 
     last = way.pop(); 
 

 
    way.reduce(function (o, k, i, kk) { 
 
     return o[k] = o[k] || (isFinite(i + 1 in kk ? kk[i + 1] : last) ? [] : {}); 
 
    }, object)[last] = value; 
 
} 
 

 
var test = {}; 
 
setValue(test, "foo.name", "Mr. Foo"); 
 
setValue(test, "foo.data[0].bar", 100); 
 
setValue(test, "and.another[2].deep", 20); 
 
console.log(test);

+0

versuchte, so etwas zu tun, aber die Arrays waren Dinge durcheinander bringen. Funktioniert die Lösung mit Arrays auf jeder Ebene? dh "A.B [0] .c" –

+0

funktioniert mit jedem Level. Wenn ein Pfad nicht auflösbar ist, gibt er 'undefined' zurück. –

+0

fantastisch, das ist eine Art Zauberei, das funktioniert perfekt. Noch eine kurze Frage: Haben Sie eine ähnliche Methode zum Setzen von Daten (auch wenn das Feld nicht definiert ist), wie: 'setValue (Objekt, Pfad, Wert)'? :) –

Verwandte Themen