wake-up-neo.net

Zugriff/Verarbeitung von (verschachtelten) Objekten, Arrays oder JSON

Ich habe eine verschachtelte Datenstruktur, die Objekte und Arrays enthält. Wie kann ich die Informationen extrahieren, d. H. Auf bestimmte oder mehrere Werte (oder Schlüssel) zugreifen?

Zum Beispiel:

var data = {
    code: 42,
    items: [{
        id: 1,
        name: 'foo'
    }, {
        id: 2,
        name: 'bar'
    }]
};

Wie kann ich auf die name des zweiten Elements in items zugreifen?

713
Felix Kling

Vorbereitungen

JavaScript hat nur einen Datentyp, der mehrere Werte enthalten kann: Object . Ein Array ist eine spezielle Objektform.

(Einfache) Objekte haben die Form

_{key: value, key: value, ...}
_

Arrays haben die Form

_[value, value, ...]
_

Sowohl Arrays als auch Objekte weisen eine _key -> value_ -Struktur auf. Schlüssel in einem Array müssen numerisch sein, wohingegen ein beliebiger String als Schlüssel in Objekten verwendet werden kann. Die Schlüssel-Wert-Paare werden auch als "properties" bezeichnet.

Auf die Eigenschaften kann entweder mit Punktnotation zugegriffen werden

_const value = obj.someProperty;
_

oder Klammernotation , wenn der Eigenschaftsname kein gültiges JavaScript wäre Bezeichnername [spec] oder der Name ist der Wert einer Variablen:

_// the space is not a valid character in identifier names
const value = obj["some Property"];

// property name as variable
const name = "some Property";
const value = obj[name];
_

Aus diesem Grund kann auf Array-Elemente nur mit der Klammernotation zugegriffen werden:

_const value = arr[5]; // arr.5 would be a syntax error

// property name / index as variable
const x = 5;
const value = arr[x];
_

Warten Sie ... was ist mit JSON?

JSON ist eine Textdarstellung von Daten, genau wie XML, YAML, CSV und andere. Um mit solchen Daten zu arbeiten, muss sie zuerst in JavaScript-Datentypen konvertiert werden, d. H. In Arrays und Objekte (und wie man damit arbeitet, wurde gerade erklärt). Wie JSON analysiert wird, erfahren Sie in der Frage JSON in JavaScript analysieren? .

Weiteres Lesematerial

Der Zugriff auf Arrays und Objekte erfordert grundlegende JavaScript-Kenntnisse. Lesen Sie daher die MDN JavaScript Guide , insbesondere die Abschnitte



Zugriff auf verschachtelte Datenstrukturen

Eine verschachtelte Datenstruktur ist ein Array oder Objekt, das sich auf andere Arrays oder Objekte bezieht, d. H. Seine Werte sind Arrays oder Objekte. Auf solche Strukturen kann zugegriffen werden, indem nacheinander eine Punkt- oder Klammernotation angewendet wird.

Hier ist ein Beispiel:

_const data = {
    code: 42,
    items: [{
        id: 1,
        name: 'foo'
    }, {
        id: 2,
        name: 'bar'
    }]
};
_

Angenommen, wir möchten auf name des zweiten Elements zugreifen.

So können wir es Schritt für Schritt machen:

Wie wir sehen können, ist data ein Objekt, daher können wir unter Verwendung der Punktnotation auf seine Eigenschaften zugreifen. Auf die Eigenschaft items wird wie folgt zugegriffen:

_data.items
_

Der Wert ist ein Array. Um auf das zweite Element zuzugreifen, müssen Sie die Klammer-Notation verwenden:

_data.items[1]
_

Dieser Wert ist ein Objekt und wir verwenden erneut die Punktnotation, um auf die Eigenschaft name zuzugreifen. So bekommen wir schließlich:

_const item_name = data.items[1].name;
_

Alternativ könnten wir für jede der Eigenschaften die Klammernotation verwenden, insbesondere wenn der Name Zeichen enthält, die ihn für die Verwendung der Punktnotation ungültig gemacht hätten:

_const item_name = data['items'][1]['name'];
_

Ich versuche, auf eine Immobilie zuzugreifen, bekomme aber nur undefined zurück?

Die meiste Zeit, wenn Sie undefined erhalten, hat das Objekt/Array einfach keine Eigenschaft mit diesem Namen.

_const foo = {bar: {baz: 42}};
console.log(foo.baz); // undefined
_

Verwenden Sie console.log oder console.dir und überprüfen Sie die Struktur des Objekts/Arrays. Die Eigenschaft, auf die Sie zugreifen möchten, ist möglicherweise tatsächlich für ein verschachteltes Objekt/Array definiert.

_console.log(foo.bar.baz); // 42
_

Was ist, wenn die Eigenschaftsnamen dynamisch sind und ich sie vorher nicht kenne?

Wenn die Eigenschaftsnamen unbekannt sind oder auf alle Eigenschaften eines Objekts/von Elementen eines Arrays zugegriffen werden soll, können Sie den folgenden Befehl verwenden: _for...in_ [MDN] Schleife für Objekte und das for[MDN] Schleife für Arrays zum Durchlaufen aller Eigenschaften/Elemente.

Objects

Um alle Eigenschaften von data zu durchlaufen, können wir das Objekt wie folgt durchlaufen:

_for (const prop in data) {
    // `prop` contains the name of each property, i.e. `'code'` or `'items'`
    // consequently, `data[prop]` refers to the value of each property, i.e.
    // either `42` or the array
}
_

Abhängig davon, woher das Objekt kommt (und was Sie tun möchten), müssen Sie möglicherweise in jeder Iteration testen, ob die Eigenschaft wirklich eine Eigenschaft des Objekts oder eine geerbte Eigenschaft ist. Sie können dies mit _Object#hasOwnProperty_ tun.[MDN] .

Alternativ zu _for...in_ mit hasOwnProperty können Sie _Object.keys_ verwenden.[MDN] um ein Array von Eigenschaftsnamen zu erhalten :

_Object.keys(data).forEach(function(prop) {
  // `prop` is the property name
  // `data[prop]` is the property value
});
_

Arrays

Um über alle Elemente des _data.items_ array zu iterieren, verwenden wir eine for -Schleife:

_for(let i = 0, l = data.items.length; i < l; i++) {
    // `i` will take on the values `0`, `1`, `2`,..., i.e. in each iteration
    // we can access the next element in the array with `data.items[i]`, example:
    // 
    // var obj = data.items[i];
    // 
    // Since each element is an object (in our example),
    // we can now access the objects properties with `obj.id` and `obj.name`. 
    // We could also use `data.items[i].id`.
}
_

Man könnte auch _for...in_ verwenden, um über Arrays zu iterieren, aber es gibt Gründe, warum dies vermieden werden sollte: Warum ist 'for (var item in list)' bei Arrays in JavaScript eine schlechte Praxis? .

Mit der zunehmenden Browserunterstützung von ECMAScript 5 wurde die Array-Methode forEach[MDN] wird auch eine interessante Alternative:

_data.items.forEach(function(value, index, array) {
    // The callback is executed for each element in the array.
    // `value` is the element itself (equivalent to `array[index]`)
    // `index` will be the index of the element in the array
    // `array` is a reference to the array itself (i.e. `data.items` in this case)
}); 
_

In Umgebungen, die ES2015 (ES6) unterstützen, können Sie auch for...of verwenden.[MDN] Schleife, die nicht nur für Arrays funktioniert, sondern für alle iterierbaren :

_for (const item of data.items) {
   // `item` is the array element, **not** the index
}
_

In jeder Iteration gibt uns _for...of_ direkt das nächste Element der Iteration, es gibt keinen "Index", auf den zugegriffen oder der verwendet werden kann.


Was ist, wenn mir die "Tiefe" der Datenstruktur unbekannt ist?

Zusätzlich zu unbekannten Schlüsseln kann auch die "Tiefe" der Datenstruktur (d. H. Wie viele verschachtelte Objekte) unbekannt sein. Wie auf tief verschachtelte Eigenschaften zugegriffen wird, hängt in der Regel von der genauen Datenstruktur ab.

Wenn jedoch die Datenstruktur sich wiederholende Muster enthält, z. Die Darstellung eines Binärbaums beinhaltet die Lösung typischerweise zu rekursiv [Wikipedia] Zugriff auf jede Ebene der Datenstruktur.

Hier ist ein Beispiel, um den ersten Blattknoten eines Binärbaums zu erhalten:

_function getLeaf(node) {
    if (node.leftChild) {
        return getLeaf(node.leftChild); // <- recursive call
    }
    else if (node.rightChild) {
        return getLeaf(node.rightChild); // <- recursive call
    }
    else { // node must be a leaf node
        return node;
    }
}

const first_leaf = getLeaf(root);
_
_const root = {
    leftChild: {
        leftChild: {
            leftChild: null,
            rightChild: null,
            data: 42
        },
        rightChild: {
            leftChild: null,
            rightChild: null,
            data: 5
        }
    },
    rightChild: {
        leftChild: {
            leftChild: null,
            rightChild: null,
            data: 6
        },
        rightChild: {
            leftChild: null,
            rightChild: null,
            data: 7
        }
    }
};
function getLeaf(node) {
    if (node.leftChild) {
        return getLeaf(node.leftChild);
    } else if (node.rightChild) {
        return getLeaf(node.rightChild);
    } else { // node must be a leaf node
        return node;
    }
}

console.log(getLeaf(root).data);_

Eine allgemeinere Möglichkeit, auf eine verschachtelte Datenstruktur mit unbekannten Schlüsseln und unbekannter Tiefe zuzugreifen, besteht darin, den Typ des Werts zu testen und entsprechend zu handeln.

In diesem Beispiel werden alle Grundwerte in einer verschachtelten Datenstruktur zu einem Array hinzugefügt (vorausgesetzt, es enthält keine Funktionen). Wenn wir auf ein Objekt (oder Array) stoßen, rufen wir toArray für diesen Wert einfach erneut auf (rekursiver Aufruf).

_function toArray(obj) {
    const result = [];
    for (const prop in obj) {
        const value = obj[prop];
        if (typeof value === 'object') {
            result.Push(toArray(value)); // <- recursive call
        }
        else {
            result.Push(value);
        }
    }
    return result;
}
_
_const data = {
  code: 42,
  items: [{
    id: 1,
    name: 'foo'
  }, {
    id: 2,
    name: 'bar'
  }]
};


function toArray(obj) {
  const result = [];
  for (const prop in obj) {
    const value = obj[prop];
    if (typeof value === 'object') {
      result.Push(toArray(value));
    } else {
      result.Push(value);
    }
  }
  return result;
}

console.log(toArray(data));_


Helfer

Da die Struktur eines komplexen Objekts oder Arrays nicht unbedingt offensichtlich ist, können Sie den Wert bei jedem Schritt überprüfen, um zu entscheiden, wie Sie sich weiterbewegen möchten. _console.log_ [MDN] und _console.dir_ [MDN] hilf uns dabei. Zum Beispiel (Ausgabe der Chrome Konsole):

_> console.log(data.items)
 [ Object, Object ]
_

Hier sehen wir, dass _data.items_ ein Array mit zwei Elementen ist, die beide Objekte sind. In der Chrome Konsole können die Objekte sogar sofort erweitert und inspiziert werden.

_> console.log(data.items[1])
  Object
     id: 2
     name: "bar"
     __proto__: Object
_

Dies sagt uns, dass _data.items[1]_ ein Objekt ist, und nach dem Erweitern sehen wir, dass es drei Eigenschaften hat, id, name und ___proto___. Letzteres ist eine interne Eigenschaft, die für die Prototypkette des Objekts verwendet wird. Die Prototypenkette und -vererbung sind für diese Antwort jedoch nicht zulässig.

1056
Felix Kling

Sie können auf diese Weise darauf zugreifen

data.items[1].name

oder

data["items"][1]["name"]

Beide Wege sind gleich.

58
vitmalina

Falls Sie versuchen, aus der Beispielstruktur über item oder id auf eine name zuzugreifen, ohne deren Position im Array zu kennen, können Sie dies am einfachsten mit underscore.js library tun:

var data = {
    code: 42,
    items: [{
        id: 1,
        name: 'foo'
    }, {
        id: 2,
        name: 'bar'
    }]
};

_.find(data.items, function(item) {
  return item.id === 2;
});
// Object {id: 2, name: "bar"}

Nach meiner Erfahrung führt die Verwendung von Funktionen höherer Ordnung anstelle von for- oder for..in-Schleifen zu Code, der einfacher zu verstehen ist und daher wartungsfreundlicher ist.

Nur meine 2 Cent.

26

Manchmal kann der Zugriff auf ein verschachteltes Objekt mit einer Zeichenfolge wünschenswert sein. Der einfache Ansatz ist zum Beispiel die erste Ebene

var obj = { hello: "world" };
var key = "hello";
alert(obj[key]);//world

Bei komplexem Json ist dies jedoch häufig nicht der Fall. Je komplexer Json wird, desto komplexer werden auch die Ansätze, um Werte innerhalb des Json zu finden. Ein rekursiver Ansatz zum Navigieren des Json ist am besten, und wie diese Rekursion genutzt wird, hängt von der Art der gesuchten Daten ab. Wenn bedingte Anweisungen vorhanden sind, kann eine json-Suche ein gutes Werkzeug sein.

Wenn die Eigenschaft, auf die zugegriffen wird, bereits bekannt ist, der Pfad jedoch komplex ist, beispielsweise in diesem Objekt

var obj = {
 arr: [
    { id: 1, name: "larry" },    
    { id: 2, name: "curly" },
    { id: 3, name: "moe" }
 ]
};

Und Sie wissen, dass Sie das erste Ergebnis des Arrays im Objekt erhalten möchten. Vielleicht möchten Sie es verwenden

var moe = obj["arr[0].name"];

Dies führt jedoch zu einer Ausnahme, da es keine Eigenschaft eines Objekts mit diesem Namen gibt. Die Lösung, um dies nutzen zu können, besteht darin, den Baumaspekt des Objekts zu reduzieren. Dies kann rekursiv erfolgen.

function flatten(obj){
 var root = {};
 (function tree(obj, index){
   var suffix = toString.call(obj) == "[object Array]" ? "]" : "";
   for(var key in obj){
    if(!obj.hasOwnProperty(key))continue;
    root[index+key+suffix] = obj[key];
    if( toString.call(obj[key]) == "[object Array]" )tree(obj[key],index+key+suffix+"[");
    if( toString.call(obj[key]) == "[object Object]" )tree(obj[key],index+key+suffix+".");   
   }
 })(obj,"");
 return root;
}

Das komplexe Objekt kann jetzt abgeflacht werden

var obj = previous definition;
var flat = flatten(obj);
var moe = flat["arr[0].name"];//moe

Hier wird ein jsFiddle Demo dieses Ansatzes verwendet.

16
Travis J

Objekte und Arrays verfügen über zahlreiche integrierte Methoden, die Ihnen bei der Datenverarbeitung helfen können.

Hinweis: In vielen Beispielen verwende ich Pfeilfunktionen . Sie sind ähnlich wie Funktionsausdrücke , binden jedoch den this-Wert lexikalisch.

Object.keys() , Object.values() (ES 2017) und Object.entries() (ES 2017)

Object.keys() gibt ein Array von Objektschlüsseln zurück, Object.values() gibt ein Array von Objektwerten zurück und Object.entries() gibt ein Array von Objektschlüsseln und entsprechenden Werten in einem Format [key, value] zurück.

const obj = {
  a: 1
 ,b: 2
 ,c: 3
}

console.log(Object.keys(obj)) // ['a', 'b', 'c']
console.log(Object.values(obj)) // [1, 2, 3]
console.log(Object.entries(obj)) // [['a', 1], ['b', 2], ['c', 3]]

Object.entries() mit einer for-of-Schleife und einer Zerstörungszuweisung

const obj = {
  a: 1
 ,b: 2
 ,c: 3
}

for (const [key, value] of Object.entries(obj)) {
  console.log(`key: ${key}, value: ${value}`)
}

Es ist sehr praktisch, das Ergebnis von Object.entries() mit einer for-of-Schleife - und Destrukturierungszuweisung zu iterieren.

Mit der For-of-Schleife können Sie Array-Elemente durchlaufen. Die Syntax lautet for (const element of array) (wir können const durch var oder let ersetzen, es ist jedoch besser, const zu verwenden, wenn element nicht geändert werden soll).

Durch die Destrukturierungszuweisung können Sie Werte aus einem Array oder einem Objekt extrahieren und sie Variablen zuweisen. In diesem Fall bedeutet const [key, value], dass anstelle des [key, value]-Arrays element das erste Element dieses Arrays key und das zweite Element value zugewiesen wird. Das ist gleichbedeutend mit:

for (const element of Object.entries(obj)) {
  const key = element[0]
       ,value = element[1]
}

Wie Sie sehen, macht die Zerstörung dies viel einfacher.

Array.prototype.every() und Array.prototype.some()

Die every()-Methode gibt true zurück, wenn die angegebene Callback-Funktion true für every - Element des Arrays zurückgibt. Die some()-Methode gibt true zurück, wenn die angegebene Callback-Funktion true für some (mindestens ein) Element zurückgibt.

const arr = [1, 2, 3]

// true, because every element is greater than 0
console.log(arr.every(x => x > 0))
// false, because 3^2 is greater than 5
console.log(arr.every(x => Math.pow(x, 2) < 5))
// true, because 2 is even (the remainder from dividing by 2 is 0)
console.log(arr.some(x => x % 2 === 0))
// false, because none of the elements is equal to 5
console.log(arr.some(x => x === 5))

Array.prototype.find() und Array.prototype.filter()

Die find()-Methoden geben das erste -Element zurück, das die bereitgestellte Rückruffunktion erfüllt. Die filter()-Methode gibt ein Array von all -Elementen zurück, das die bereitgestellte Rückruffunktion erfüllt.

const arr = [1, 2, 3]

// 2, because 2^2 !== 2
console.log(arr.find(x => x !== Math.pow(x, 2)))
// 1, because it's the first element
console.log(arr.find(x => true))
// undefined, because none of the elements equals 7
console.log(arr.find(x => x === 7))

// [2, 3], because these elements are greater than 1
console.log(arr.filter(x => x > 1))
// [1, 2, 3], because the function returns true for all elements
console.log(arr.filter(x => true))
// [], because none of the elements equals neither 6 nor 7
console.log(arr.filter(x => x === 6 || x === 7))

Array.prototype.map()

Die map()-Methode gibt ein Array mit den Ergebnissen des Aufrufs einer bereitgestellten Rückruffunktion für die Array-Elemente zurück.

const arr = [1, 2, 3]

console.log(arr.map(x => x + 1)) // [2, 3, 4]
console.log(arr.map(x => String.fromCharCode(96 + x))) // ['a', 'b', 'c']
console.log(arr.map(x => x)) // [1, 2, 3] (no-op)
console.log(arr.map(x => Math.pow(x, 2))) // [1, 4, 9]
console.log(arr.map(String)) // ['1', '2', '3']

Array.prototype.reduce()

Die reduce()-Methode reduziert ein Array auf einen einzelnen Wert, indem die bereitgestellte Callback-Funktion mit zwei Elementen aufgerufen wird.

const arr = [1, 2, 3]

// Sum of array elements.
console.log(arr.reduce((a, b) => a + b)) // 6
// The largest number in the array.
console.log(arr.reduce((a, b) => a > b ? a : b)) // 3

Die reduce()-Methode verwendet einen optionalen zweiten Parameter, der den Anfangswert darstellt. Dies ist nützlich, wenn das Array, auf dem Sie reduce() aufrufen, null oder ein Element enthalten kann. Wenn wir beispielsweise eine Funktion sum() erstellen wollten, die ein Array als Argument verwendet und die Summe aller Elemente zurückgibt, könnten wir es so schreiben:

const sum = arr => arr.reduce((a, b) => a + b, 0)

console.log(sum([]))     // 0
console.log(sum([4]))    // 4
console.log(sum([2, 5])) // 7

14

Diese Frage ist ziemlich alt, so ein zeitgemäßes Update. Mit dem Beginn von ES2015 gibt es Alternativen, um die gewünschten Daten zu erhalten. Es gibt jetzt ein Feature namens object destructuring für den Zugriff auf verschachtelte Objekte.

const data = {
  code: 42,
  items: [{
    id: 1,
    name: 'foo'
  }, {
    id: 2,
    name: 'bar'
  }]
};

const {
  items: [, {
    name: secondName
  }]
} = data;

console.log(secondName);

Das obige Beispiel erstellt eine Variable mit dem Namen secondName aus dem name-Schlüssel aus einem Array mit dem Namen items. Der einsame , sagt, das erste Objekt im Array zu überspringen. 

Für dieses Beispiel ist es wahrscheinlich ein Overkill, da der einfache Array-Zugriff einfacher zu lesen ist. Dies ist jedoch nützlich, wenn Objekte im Allgemeinen auseinandergebrochen werden. 

Dies ist eine sehr kurze Einführung in Ihren speziellen Anwendungsfall. Destructuring kann eine ungewöhnliche Syntax sein, an die man sich zunächst gewöhnen kann. Ich empfehle, die Dokumentation zu Mozilla Destructuring Assignment zu lesen, um mehr zu erfahren.

9
Alex KeySmith

Die Verwendung von JSONPath wäre eine der flexibelsten Lösungen, wenn Sie eine Bibliothek hinzufügen möchten: https://github.com/s3u/JSONPath (Knoten und Browser)

Für Ihren Anwendungsfall wäre der Json-Pfad:

$..items[1].name

so:

var secondName = jsonPath.eval(data, "$..items[1].name");
7
Andrejs

Ich bevorzuge JQuery. Es ist sauberer und leicht zu lesen.

 $.each($.parseJSON(data), function (key, value) {
    alert(value.<propertyname>);
});

6
Rudy Hinojosa

Um auf ein verschachteltes Attribut zuzugreifen, müssen Sie seinen Namen angeben und dann das Objekt durchsuchen.

Wenn Sie den genauen Pfad bereits kennen, können Sie ihn wie folgt in Ihrem Skript hartcodieren:

data['items'][1]['name']

diese arbeiten auch -

data.items[1].name
data['items'][1].name
data.items[1]['name']

Wenn Sie den genauen Namen nicht kennen oder ein Benutzer den Namen für Sie bereitstellt. Dann ist ein dynamisches Durchsuchen der Datenstruktur erforderlich. Einige haben hier vorgeschlagen, dass die Suche mit einer for-Schleife durchgeführt werden kann, aber es gibt eine sehr einfache Möglichkeit, einen Pfad mithilfe von Array.reduce zu durchsuchen.

const data = { code: 42, items: [{ id: 1, name: 'foo' }, { id: 2, name: 'bar' }] }
const path = [ 'items', '1', 'name']
let result = path.reduce((a,v) => a[v], data)

Der Pfad ist eine Art zu sagen: Nehmen Sie zuerst das Objekt mit dem Schlüssel items, der zufällig ein Array ist. Nehmen Sie dann das 1-st-Element (0 Index-Arrays). Als letztes nehmen Sie das Objekt mit dem Schlüssel name in diesem Array-Element, das zufällig die Zeichenfolge bar ist.

Wenn Sie einen sehr langen Pfad haben, können Sie sogar String.split verwenden, um dies alles zu erleichtern.

'items.1.name'.split('.').reduce((a,v) => a[v], data)

Dies ist nur einfaches JavaScript, ohne dass Bibliotheken von Drittanbietern wie jQuery oder lodash verwendet werden.

6
Evgeny

Sie könnten die lodash _get-Funktion verwenden:

var object = { 'a': [{ 'b': { 'c': 3 } }] };

_.get(object, 'a[0].b.c');
// => 3
5
Sergey

Wenn Sie nach einem oder mehreren Objekten suchen, die bestimmte Kriterien erfüllen, haben Sie mit query-js einige Optionen

//will return all elements with an id larger than 1
data.items.where(function(e){return e.id > 1;});
//will return the first element with an id larger than 1
data.items.first(function(e){return e.id > 1;});
//will return the first element with an id larger than 1 
//or the second argument if non are found
data.items.first(function(e){return e.id > 1;},{id:-1,name:""});

Es gibt auch ein single und ein singleOrDefault, die ähnlich wie first bzw. firstOrDefault funktionieren. Der einzige Unterschied ist, dass sie werfen, wenn mehr als eine Übereinstimmung gefunden wird.

zur weiteren Erklärung von query-js können Sie mit diesem beginnen post

5
Rune FS

Zugriff auf dynamisch mehrstufige Objekte.

var obj = {
  name: "salut",
  subobj: {
    subsubobj: {
      names: "I am sub sub obj"
    }
  }
};

var level = "subobj.subsubobj.names";
level = level.split(".");

var currentObjState = obj;

for (var i = 0; i < level.length; i++) {
  currentObjState = currentObjState[level[i]];
}

console.log(currentObjState);

Geige arbeiten: https://jsfiddle.net/andreitodorut/3mws3kjL/

3
Andrei Todorut
var ourStorage = {


"desk":    {
    "drawer": "stapler"
  },
"cabinet": {
    "top drawer": { 
      "folder1": "a file",
      "folder2": "secrets"
    },
    "bottom drawer": "soda"
  }
};
ourStorage.cabinet["top drawer"].folder2; // Outputs -> "secrets"

oder

//parent.subParent.subsubParent["almost there"]["final property"]

Verwenden Sie grundsätzlich einen Punkt zwischen jedem Nachkommen, der sich darunter entfaltet. Wenn Sie Objektnamen aus zwei Strings erstellen, müssen Sie die Schreibweise ["obj Name"] verwenden. Andernfalls würde nur ein Punkt ausreichen.

Quelle: https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/basic-javascript/accessing-nested-objects

der Zugriff auf verschachtelte Arrays würde folgendermaßen erfolgen:

var ourPets = [
  {
    animalType: "cat",
    names: [
      "Meowzer",
      "Fluffy",
      "Kit-Cat"
    ]
  },
  {
    animalType: "dog",
    names: [
      "Spot",
      "Bowser",
      "Frankie"
    ]
  }
];
ourPets[0].names[1]; // Outputs "Fluffy"
ourPets[1].names[0]; // Outputs "Spot"

Quelle: https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/basic-javascript/accessing-nested-arrays/

3
Johnny

Der Unterstrich js Way

Dies ist eine JavaScript-Bibliothek, die eine Fülle nützlicher functional programming-Helfer zur Verfügung stellt, ohne eingebaute Objekte zu erweitern.

Lösung:

var data = {
  code: 42,
  items: [{
    id: 1,
    name: 'foo'
  }, {
    id: 2,
    name: 'bar'
  }]
};

var item = _.findWhere(data.items, {
  id: 2
});
if (!_.isUndefined(item)) {
  console.log('NAME =>', item.name);
}

//using find - 

var item = _.find(data.items, function(item) {
  return item.id === 2;
});

if (!_.isUndefined(item)) {
  console.log('NAME =>', item.name);
}
3
Mohan Dere

Alte Frage, aber wie gesagt niemand lodash (nur Unterstrich).

Falls Sie lodash bereits in Ihrem Projekt einsetzen, finde ich eine elegante Möglichkeit, dies in einem komplexen Beispiel zu tun:

Opt 1

_.get(response, ['output', 'fund', 'data', '0', 'children', '0', 'group', 'myValue'], '')

gleich wie:

Opt 2

response.output.fund.data[0].children[0].group.myValue

Der Unterschied zwischen der ersten und der zweiten Option besteht darin, dass in der Option Opt 1 /, wenn eine der Eigenschaften (undefiniert) im Pfad fehlt, kein Fehler angezeigt wird, der dritte Parameter zurückgegeben wird.

Für den Array-Filter hat lodash _.find(), ich würde aber lieber die reguläre filter() verwenden. Aber ich denke immer noch, dass die obige Methode _.get() sehr nützlich ist, wenn mit wirklich komplexen Daten gearbeitet wird. Ich hatte in der Vergangenheit wirklich komplexe APIs und es war praktisch!

Ich hoffe, es kann nützlich sein für diejenigen, die nach Optionen suchen, um wirklich komplexe Daten zu manipulieren, die der Titel impliziert.

3
Ventura

Ich glaube nicht, dass der Fragesteller nur ein verschachteltes Objekt betrifft, daher zeige ich die folgende Demo, um zu zeigen, wie auf den Knoten eines tief geschachtelten Json-Objekts zugegriffen werden kann. Alles klar, suchen wir den Knoten mit der ID '5'.

var data = {
  code: 42,
  items: [{
    id: 1,
    name: 'aaa',
    items: [{
        id: 3,
        name: 'ccc'
      }, {
        id: 4,
        name: 'ddd'
      }]
    }, {
    id: 2,
    name: 'bbb',
    items: [{
        id: 5,
        name: 'eee'
      }, {
        id: 6,
        name: 'fff'
      }]
    }]
};

var jsonloop = new JSONLoop(data, 'id', 'items');

jsonloop.findNodeById(data, 5, function(err, node) {
  if (err) {
    document.write(err);
  } else {
    document.write(JSON.stringify(node, null, 2));
  }
});
<script src="https://rawgit.com/dabeng/JSON-Loop/master/JSONLoop.js"></script>

2
dabeng

Nur für den Fall, dass jemand diese Frage in 2017 oder später besucht und nach einer einfach zu merkenden Art und Weise sucht. Hier ist ein ausführlicher Blogbeitrag über Auf verschachtelte Objekte in JavaScript zugreifen ohne bamboozled von 

Eigenschaft 'foo' von undefined kann nicht gelesen werden Fehler

1. Das verschachtelte Objektzugriffsmuster von Oliver Steele

Der einfachste und sauberste Weg ist das verschachtelte Objektzugriffsmuster von Oliver Steele

const name = ((user || {}).personalInfo || {}).name;

Mit dieser Notation werden Sie nie in Kontakt geraten

Eigenschaft 'name' von undefined kann nicht gelesen werden

Sie prüfen grundsätzlich, ob ein Benutzer vorhanden ist. Wenn nicht, erstellen Sie sofort ein leeres Objekt. Auf diese Weise wird auf den Schlüssel der nächsten Ebene immer von einem vorhandenen Objekt oder einem leeren Objekt aus zugegriffen, aber niemals von undefiniert.

2. Greifen Sie mit Array Reduce auf verschachtelte Objekte zu

Um auf verschachtelte Arrays zugreifen zu können, können Sie ein eigenes Array schreiben, das util reduziert.

const getNestedObject = (nestedObj, pathArr) => {
    return pathArr.reduce((obj, key) =>
        (obj && obj[key] !== 'undefined') ? obj[key] : undefined, nestedObj);
}

// pass in your object structure as array elements
const name = getNestedObject(user, ['personalInfo', 'name']);

// to access nested array, just pass in array index as an element the path array.
const city = getNestedObject(user, ['personalInfo', 'addresses', 0, 'city']);
// this will return the city from the first address item.

Es gibt auch einen hervorragenden Typ, der die minimale Bibliothek typy behandelt, die all dies für Sie erledigt.

1
Dinesh Pandiyan

Hier ist ein dynamischer Ansatz - Ihr 'tiefer' Schlüssel ist der String 'items[1].name' (Sie können die Array-Notation [i] auf jeder Ebene verwenden) - wenn der Schlüssel ungültig ist, wird undefined zurückgegeben.

let deep = (o,k) => {
  return k.split('.').reduce((a,c,i) => {
    let m=c.match(/(.*?)\[(\d*)\]/);
    if(m && a!=null && a[m[1]]!=null) return a[m[1]][+m[2]];
    return a==null ? a: a[c];
  },o)
}
var data = {
    code: 42,
    items: [
      { id: 1, name: 'foo'}, 
      { id: 2, name: 'bar'},
   ]
};

let deep = (o,k) => {
  return k.split('.').reduce((a,c,i) => {
    let m=c.match(/(.*?)\[(\d*)\]/);
    if(m && a!=null && a[m[1]]!=null) return a[m[1]][+m[2]];
    return a==null ? a: a[c];
  },o)
}

console.log( deep(data,'items[1].name') );
0

Meine stringjson stammt aus der PHP -Datei, aber ich gebe hier in var an. Wenn ich meinen json direkt in obj nehme, zeigt das nichts, warum ich meine json-Datei als ablege

var obj=JSON.parse(stringjson); also danach bekomme ich message obj und zeige es im Benachrichtigungsfeld dann bekomme ich data das ist json array und speichere es in einer variablen ArrObj dann lese ich das erste Objekt dieses Arrays mit Schlüsselwert wie diesem ArrObj[0].id

     var stringjson={
        "success": true,
        "message": "working",
        "data": [{
                  "id": 1,
                  "name": "foo"
         }]
      };

                var obj=JSON.parse(stringjson);
                var key = "message";
                alert(obj[key]);
                var keyobj = "data";
                var ArrObj =obj[keyobj];

                alert(ArrObj[0].id);
0
Manthan Patel

Mit der Funktion grep von jQuery können Sie durch ein Array filtern:

var data = {
    code: 42,
    items: [{
        id: 1,
        name: 'foo'
    }, {
        id: 2,
        name: 'bar'
    }]
};

$.grep(data.items, function(item) {
    if (item.id === 2) {
        console.log(item.id); //console id of item
        console.log(item.name); //console name of item
        console.log(item); //console item object
        return item; //returns item object
    }

});
// Object {id: 2, name: "bar"}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

0
user7110739

Ein pythonischer, rekursiver und funktionaler Ansatz zum Entschlüsseln beliebiger JSON-Bäume:

handlers = {
    list:  iterate,
    dict:  delve,
    str:   emit_li,
    float: emit_li,
}

def emit_li(stuff, strong=False):
    emission = '<li><strong>%s</strong></li>' if strong else '<li>%s</li>'
    print(emission % stuff)

def iterate(a_list):
    print('<ul>')
    map(unravel, a_list)
    print('</ul>')

def delve(a_dict):
    print('<ul>')
    for key, value in a_dict.items():
        emit_li(key, strong=True)
        unravel(value)
    print('</ul>')

def unravel(structure):
    h = handlers[type(structure)]
    return h(structure)

unravel(data)

wobei data eine Python-Liste ist (analysiert aus einer JSON-Textzeichenfolge):

data = [
    {'data': {'customKey1': 'customValue1',
           'customKey2': {'customSubKey1': {'customSubSubKey1': 'keyvalue'}}},
  'geometry': {'location': {'lat': 37.3860517, 'lng': -122.0838511},
               'viewport': {'northeast': {'lat': 37.4508789,
                                          'lng': -122.0446721},
                            'southwest': {'lat': 37.3567599,
                                          'lng': -122.1178619}}},
  'name': 'Mountain View',
  'scope': 'GOOGLE',
  'types': ['locality', 'political']}
]
0
pX0r