2017-11-23 2 views
0

Ich glaube nicht „verschachtelte Werte“ der richtige Begriff ist, aber hier ist, was ich versuche zu tun:Wie durch Objektschlüsselwerten und verschachtelte Werte Schleife

Lasst uns sagen, dass ich ein Objekt, das so aussieht, dies:

{ 
    title: 'Foo', 
    content: { 
     top: 'Bar', 
     bottom: 'Baz' 
    } 
} 

Und ich möchte überprüfen, ob entweder title oder content.top oder content.bottom eine bestimmte Zeichenfolge enthält.

ich gefunden habe, dass ich kann Schleife durch eine Objektschlüssel mit etwas wie folgt aus:

for (var property in object) { 
    if (object.hasOwnProperty(property)) { 
     // do stuff 
    } 
} 

Was aber, wenn der Schlüssel ein Objekt in sich selbst und andere Tasten enthält? Was, wenn diese Schlüssel auch Objekte mit verschiedenen Schlüsseln sind? Gibt es also eine Möglichkeit, das gesamte Objekt "tief" zu durchsuchen, so dass es alle Werte durchsucht, egal wie tief die Werte "verschachtelt" sind?

+0

Wollen Sie durch jeden Wert in einer Schleife? Oder weißt du genau, welchen du brauchst? Wenn Sie die genaue Eigenschaft kennen, können Sie Punktnotation verwenden, zB 'myObject.content.top' – Sidney

+0

Ja, ich möchte alle Werte durchlaufen, weil ich mit verschiedenen Objekten mit unterschiedlichen Werten arbeite (und sie sind viele daher ist es unpraktisch, sie manuell hinzuzufügen. – Leon

+0

Was möchten Sie zurückgeben? Und nur das erste Spiel finden? – charlietfl

Antwort

4

Verschachtelte Objekte bilden eine rekursive Datenstruktur, die als Baum bezeichnet wird, und ein Baum ist leicht mit rekursiven Funktionen durchsuchbar. Rekursive Funktionen sind Funktionen, die sich selbst nennen, wie die folgenden browse Funktion  :

var tree = { 
 
    a: "azerty", 
 
    child: { 
 
    q: "qwerty" 
 
    } 
 
}; 
 

 
browse(tree); 
 

 
function browse (tree) { 
 
    for (var k in tree) { 
 
    if (isTree(tree[k])) { 
 
     browse(tree[k]); 
 
    } else { 
 
     console.log(k, tree[k]); 
 
    } 
 
    } 
 
} 
 

 
function isTree (x) { 
 
    return Object.prototype.toString.call(x) === "[object Object]"; 
 
}

Allerdings ist diese Funktion entwickelt, um die gleiche Aufgabe immer und immer wieder durchzuführen. Ein generischer Ansatz wäre es, Operationen auf jedes Blatt   angewandt auszuzulagern:

var tree = { 
 
    a: 'azerty', 
 
    child: { 
 
    q: 'qwerty' 
 
    } 
 
}; 
 

 
browse(tree, log); 
 
browse(tree, searchQ); 
 

 
function browse (tree, operation) { 
 
    for (var k in tree) { 
 
    if (isTree(tree[k])) { 
 
     browse(tree[k], operation); 
 
    } else { 
 
     operation(k, tree[k]); 
 
    } 
 
    } 
 
} 
 

 
function log (label, leaf) { 
 
    console.log("logged", label, leaf); 
 
} 
 

 
function searchQ (label, leaf) { 
 
    if (leaf.indexOf('q') !== -1) { 
 
    console.log("found", label, leaf); 
 
    } 
 
} 
 

 
function isTree (x) { 
 
    return Object.prototype.toString.call(x) === "[object Object]"; 
 
}

+0

Danke für das Update! Eine Frage jedoch: Wie würde ich mit dieser Methode eine Reihe von "Bäumen" durchsuchen, wie würde ich den "oberen" Baum zurückgeben, anstatt einen verschachtelten Baum? Wenn Sie wissen, was ich meine .. – Leon

+0

Nun, wenn ich die Browse-Funktion ein zweites Mal ausführen, wird der Baumparameter Tree.bild, anstatt Baum, oder? Ich möchte den Baum zurückgeben können, wenn ein Spiel gefunden wurde. Aber ich denke, dass ich das lösen kann, indem ich der Funktion, mit der ich den ursprünglichen Baum übergeben kann, ein zweites Argument hinzufüge. – Leon

+0

Grundsätzlich in der searchQ -Funktion, ich möchte es die "Baum" Variable protokollieren, anstelle der tatsächlichen Struktur, die den Wert enthält. Dies ist, weil ich ein Array von Objekten durchlaufen und ich möchte das Objekt, das enthält der Wert, nicht der Baum. Hier können Sie sehen, was ich meine: https://jsfiddle.net/g9nnr9xu/1/. Es protokolliert jetzt {top: "test2", unten: "test3"}, aber ich möchte, dass es den Baum protokolliert, den ich in der forEach-Schleife übergebe. Entschuldigung, wenn ich das schlecht erkläre .. Aber ich kann es mit dem Hinzufügen eines anderen Parameters beheben, so jetzt habe ich es funktioniert :) – Leon

Verwandte Themen