Suchen nach Schlüssel tief in einem verschachtelten Array

Lesezeit: 7 Minuten

Suchen nach Schlussel tief in einem verschachtelten Array
Harry

Nehmen wir an, ich habe ein Objekt:

[
    {
        'title': "some title"
        'channel_id':'123we'
        'options': [
                    {
                'channel_id':'abc'
                'image':'http://asdasd.com/all-inclusive-block-img.jpg'
                'title':'All-Inclusive'
                'options':[
                    {
                        'channel_id':'dsa2'
                        'title':'Some Recommends'
                        'options':[
                            {
                                'image':'http://www.asdasd.com'                                 'title':'Sandals'
                                'id':'1'
                                'content':{
                                     ...

I want to find the one object where the id is 1. Is there a function for something like this? I could use Underscore’s _.filter method, but I would have to start at the top and filter down.

1646246108 654 Suchen nach Schlussel tief in einem verschachtelten Array
Zach

Recursion is your friend. I updated the function to account for property arrays:

function getObject(theObject) {
    var result = null;
    if(theObject instanceof Array) {
        for(var i = 0; i < theObject.length; i++) {
            result = getObject(theObject[i]);  if (Ergebnis) {break;  } } } else { for(var prop in theObject) { console.log(prop + ': ' + theObject[prop]);  if(prop == 'id') { if(theObject[prop] == 1) { das Objekt zurückgeben;  } } if(dasObjekt[prop] Instanz des Objekts ||  das Objekt[prop] instanceof Array) { result = getObject(theObject[prop]);  if (Ergebnis) {break;  } } } } Ergebnis zurückgeben;  }

aktualisierte jsFiddle: http://jsfiddle.net/FM3qu/7/

  • Aber warten Sie, schauen Sie sich meinen Code an, Optionen könnten viele Objekte haben [{},{}]. wie würde das funktionieren?

    – Harry

    20. März 2013 um 13:18 Uhr

  • Dort. Ich habe bereits erwähnt, dass es aktualisiert werden musste, um Arrays zu berücksichtigen, also los geht’s.

    – Zach

    20. März 2013 um 13:32 Uhr

  • Dies funktioniert nicht, wenn Sie mehr als ein Objekt in den Optionen haben

    – Harry

    21. März 2013 um 9:29 Uhr

  • Fest. Ich habe die Ergebnisvariable und die Else-Logik hinzugefügt. Das aktualisierte jsFiddle zeigt, dass es funktioniert.

    – Zach

    21. März 2013 um 13:48 Uhr

  • Zack, ich habe deinen Code ein wenig modifiziert, er funktioniert jetzt gut. Vielen Dank! Anscheinend kann ich im Moment nicht auf jsfiddle zugreifen. Ich werde meine Änderungen teilen, sobald es funktioniert

    – Harry

    22. März 2013 um 9:13 Uhr


Was für mich funktioniert hat, war dieser faule Ansatz, nicht algorithmisch faul;)

if( JSON.stringify(object_name).indexOf("key_name") > -1 ) {
    console.log("Key Found");
}
else{
    console.log("Key not Found");
}

  • Was haltet ihr davon, stattdessen Folgendes zu verwenden:if( JSON.stringify(object_name).indexOf('{"key_name":') > -1 ) {einschließlich der linken geschweiften Klammer, doppelten Anführungszeichen und dem Doppelpunkt, den JSON.stringify hinzufügt? Ich denke, es könnte eine nette Doppelprüfung sein, um sicherzustellen, dass der Schlüsselname tatsächlich ein Schlüssel ist und nicht irgendwie im “Wert” -Teil.

    – Edwardsmarkf

    22. März 2019 um 19:01 Uhr


  • Potentiell gut schlägt jedoch Tests fehl, die diesen key_name irgendwo in einem Wert haben. Gibt auch nicht das Objekt zurück, das die ID enthält

    – Ranga

    19. Mai 2019 um 3:01 Uhr

  • @Ranga … einverstanden, diese Lösung funktioniert nur, wenn Sie nur überprüfen müssen, ob der Schlüssel in einem Objekt vorhanden ist, vorausgesetzt, dass der key_name nicht in einem der Werte vorhanden ist …. Obwohl wir den Code ändern können um ‘”‘ um den Schlüsselnamen innerhalb der indexOf-Funktion einzuschließen, wenn wir sicherstellen müssen, dass es nur in Schlüsseln vorhanden ist. (Wiederum sollte key_name mit ‘”‘ um ihn herum nicht in den Werten vorhanden sein.

    – abhinav1602

    19. Mai 2019 um 12:20 Uhr

  • Ich liebe es! JSON.stringify(object).includes(text)

    – Marcelo Pereira Rodrigues

    5. Dezember 2019 um 4:18 Uhr

  • Das findet heraus wenn der Schlüssel ist vorhanden, aber das OP fragt, wie das Objekt abgerufen werden soll, dessen id-Eigenschaft einen Wert von 1 hat. Dies würde eine Antwort auf stackoverflow.com/questions/2631001/… geben (mit Ausnahme der Tatsache, dass es übereinstimmt, ob die Zeichenfolge vorhanden ist irgendwo im JSON, nicht dass es den Schlüssel hat.

    – Ketzeraffe

    18. August 2021 um 14:41 Uhr

1646246109 992 Suchen nach Schlussel tief in einem verschachtelten Array
haitaka

Wenn Sie das erste Element erhalten möchten, dessen ID 1 ist, während das Objekt durchsucht wird, können Sie diese Funktion verwenden:

function customFilter(object){
    if(object.hasOwnProperty('id') && object["id"] == 1)
        return object;

    for(var i=0; i<Object.keys(object).length; i++){
        if(typeof object[Object.keys(object)[i]] == "object"){
            var o = customFilter(object[Object.keys(object)[i]]);
            if(o != null)
                return o;
        }
    }

    return null;
}

Wenn Sie alle Elemente erhalten möchten, deren ID 1 ist, dann (alle Elemente, deren ID 1 ist, werden im Ergebnis gespeichert, wie Sie sehen):

function customFilter(object, result){
    if(object.hasOwnProperty('id') && object.id == 1)
        result.push(object);

    for(var i=0; i<Object.keys(object).length; i++){
        if(typeof object[Object.keys(object)[i]] == "object"){
            customFilter(object[Object.keys(object)[i]], result);
        }
    }
}

  • Ihre Lösung ist besser als die von @regularmike vorgeschlagene, da ich sie anpassen könnte, indem ich Schlüssel- und Wertsuche hinzufüge. Bei deinem funktioniert es, bei ihm nicht. jsfiddle.net/76fp54xt Arbeitsbeispiel

    – Julian Pinzaru

    31. Januar 2019 um 23:17 Uhr

1646246110 388 Suchen nach Schlussel tief in einem verschachtelten Array
Bestimmte Leistung

Eine andere (etwas alberne) Option besteht darin, die natürlich rekursive Natur von auszunutzen JSON.stringifyund übergebe es a Ersatzfunktion die während des Stringifizierungsprozesses auf jedem verschachtelten Objekt ausgeführt wird:

const input = [{
  'title': "some title",
  'channel_id': '123we',
  'options': [{
    'channel_id': 'abc',
    'image': 'http://asdasd.com/all-inclusive-block-img.jpg',
    'title': 'All-Inclusive',
    'options': [{
      'channel_id': 'dsa2',
      'title': 'Some Recommends',
      'options': [{
        'image': 'http://www.asdasd.com',
        'title': 'Sandals',
        'id': '1',
        'content': {}
      }]
    }]
  }]
}];

console.log(findNestedObj(input, 'id', '1'));

function findNestedObj(entireObj, keyToFind, valToFind) {
  let foundObj;
  JSON.stringify(entireObj, (_, nestedValue) => {
    if (nestedValue && nestedValue[keyToFind] === valToFind) {
      foundObj = nestedValue;
    }
    return nestedValue;
  });
  return foundObj;
};

Suchen nach Schlussel tief in einem verschachtelten Array
Julian Pinzaru

Verbesserte @haitaka-Antwort unter Verwendung des Schlüssels und des Prädikats

function  deepSearch (object, key, predicate) {
    if (object.hasOwnProperty(key) && predicate(key, object[key]) === true) return object

    for (let i = 0; i < Object.keys(object).length; i++) {
      let value = object[Object.keys(object)[i]];
      if (typeof value === "object" && value != null) {
        let o = deepSearch(object[Object.keys(object)[i]], key, predicate)
        if (o != null) return o
      }
    }
    return null
}

Dies kann also aufgerufen werden als:

var result = deepSearch(myObject, 'id', (k, v) => v === 1);

oder

var result = deepSearch(myObject, 'title', (k, v) => v === 'Some Recommends');

Hier ist die Demo: http://jsfiddle.net/a21dx6c0/

BEARBEITET

Auf die gleiche Weise können Sie mehr als ein Objekt finden

function deepSearchItems(object, key, predicate) {
        let ret = [];
        if (object.hasOwnProperty(key) && predicate(key, object[key]) === true) {
            ret = [...ret, object];
        }
        if (Object.keys(object).length) {
            for (let i = 0; i < Object.keys(object).length; i++) {
                let value = object[Object.keys(object)[i]];
                if (typeof value === "object" && value != null) {
                    let o = this.deepSearchItems(object[Object.keys(object)[i]], key, predicate);
                    if (o != null && o instanceof Array) {
                        ret = [...ret, ...o];
                    }
                }
            }
        }
        return ret;
    }

  • Notiz: typeof null === 'object', wenn also irgendwelche Werte im Objekt null sind, führen sie dazu, dass die Funktion abstürzt, wenn sie versucht, zu rekursieren. Sie sollten also auch den Wahrheitsgehalt überprüfen, bevor Sie wiederkehren.

    – Raffi

    21. Juli 2019 um 12:50 Uhr

  • @Rafi danke für die Erwähnung, bearbeitete die Antwort.

    – Julian Pinzaru

    27. August 2020 um 22:48 Uhr

1646246111 229 Suchen nach Schlussel tief in einem verschachtelten Array
Alex Quan

Ich habe diese Seite beim Googeln nach ähnlichen Funktionen gefunden. Basierend auf der Arbeit von Zach und regularmike habe ich eine andere Version erstellt, die meinen Bedürfnissen entspricht.
Übrigens, tolle Arbeit Zah und Regularmike! Ich poste den Code hier:

function findObjects(obj, targetProp, targetValue, finalResults) {

  function getObject(theObject) {
    let result = null;
    if (theObject instanceof Array) {
      for (let i = 0; i < theObject.length; i++) {
        getObject(theObject[i]);
      }
    }
    else {
      for (let prop in theObject) {
        if(theObject.hasOwnProperty(prop)){
          console.log(prop + ': ' + theObject[prop]);
          if (prop === targetProp) {
            console.log('--found id');
            if (theObject[prop] === targetValue) {
              console.log('----found porop', prop, ', ', theObject[prop]);
              finalResults.push(theObject);
            }
          }
          if (theObject[prop] instanceof Object || theObject[prop] instanceof Array){
            getObject(theObject[prop]);
          }
        }
      }
    }
  }

  getObject(obj);

}

Was es tut, ist, dass es jedes Objekt darin findet obj mit Eigenschaftsname und Wert passend zu targetProp und targetValue und wird es auf die schieben finalResults Reihe. Und hier ist die jsfiddle zum Herumspielen:
https://jsfiddle.net/alexQch/5u6q2ybc/

  • Notiz: typeof null === 'object', wenn also irgendwelche Werte im Objekt null sind, führen sie dazu, dass die Funktion abstürzt, wenn sie versucht, zu rekursieren. Sie sollten also auch den Wahrheitsgehalt überprüfen, bevor Sie wiederkehren.

    – Raffi

    21. Juli 2019 um 12:50 Uhr

  • @Rafi danke für die Erwähnung, bearbeitete die Antwort.

    – Julian Pinzaru

    27. August 2020 um 22:48 Uhr

1646246112 595 Suchen nach Schlussel tief in einem verschachtelten Array
Dominik791

Ich habe zu diesem Zweck eine Bibliothek erstellt: https://github.com/dominik791/obj-traverse

Sie können verwenden findFirst() Methode so:

var foundObject = findFirst(rootObject, 'options', { 'id': '1' });

Und nun foundObject Variable speichert einen Verweis auf das gesuchte Objekt.

914950cookie-checkSuchen nach Schlüssel tief in einem verschachtelten Array

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy