688 Stimmen

Zugriff auf verschachtelte JavaScript-Objekte und -Arrays über einen String-Pfad

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 diesen Variablen auf die Daten zugreifen:

var part1name = "part1.name";
var part2quantity = "part2.qty";
var part3name1 = "part3[0].name";

part1name sollte gefüllt werden mit someObject.part1.name Wert, der "Teil 1" ist. Dasselbe gilt für part2quantity, das mit 60 gefüllt ist.

Gibt es irgendwie zu erreichen dies entweder mit reinen Javascript oder JQuery?

0 Stimmen

Sie sind sich nicht sicher, was Sie hier fragen? Möchten Sie part1.name abfragen können und den Text "part1.name" zurückerhalten? Oder möchten Sie den in part1.name gespeicherten Wert abrufen?

0 Stimmen

Haben Sie versucht, etwas zu tun wie var part1name = someObject.part1name; `

1 Stimmen

@BonyT : Ich möchte someObject.part1.name abfragen und den Wert davon zurückgeben ("Part 1"). Ich möchte jedoch, dass die Abfrage (ich nannte sie "den Schlüssel") in einer Variablen 'part1name' gespeichert wird. Vielen Dank für Ihre Antwort. @3nigma : Das habe ich sicherlich. Aber das ist nicht meine Absicht. Vielen Dank für die Antwort.

0voto

Jodo Punkte 4057

Anstelle eines Strings kann auch ein Array verwendet werden, das verschachtelte Objekte und Arrays adressiert, z.B.: ["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 Zustand von verschachtelten Strukturen ändern.

let state = {
        test: "test_value",
        nested: {
            level1: "level1 value"
        },
        arr: [1, 2, 3],
        nested_arr: {
            arr: ["buh", "bah", "foo"]
        }
    }

function handleChange(value, fields) {
    let update_field = state;
    for(var i = 0; i < fields.length - 1; i++){
        update_field = update_field[fields[i]];
    }
    update_field[fields[fields.length-1]] = value;
}

handleChange("update", ["test"]);
handleChange("update_nested", ["nested","level1"]);
handleChange(100, ["arr",0]);
handleChange('changed_foo', ["nested_arr", "arr", 3]);
console.log(state);

0voto

Tamb Punkte 728

Aufbauend auf der Antwort von Alnitak:

if(!Object.prototype.byString){
  //NEW byString which can update values
Object.prototype.byString = function(s, v, o) {
  var _o = o || this;
      s = s.replace(/\[(\w+)\]/g, '.$1'); // CONVERT INDEXES TO PROPERTIES
      s = s.replace(/^\./, ''); // STRIP A LEADING DOT
      var a = s.split('.'); //ARRAY OF STRINGS SPLIT BY '.'
      for (var i = 0; i < a.length; ++i) {//LOOP OVER ARRAY OF STRINGS
          var k = a[i];
          if (k in _o) {//LOOP THROUGH OBJECT KEYS
              if(_o.hasOwnProperty(k)){//USE ONLY KEYS WE CREATED
                if(v !== undefined){//IF WE HAVE A NEW VALUE PARAM
                  if(i === a.length -1){//IF IT'S THE LAST IN THE ARRAY
                    _o[k] = v;
                  }
                }
                _o = _o[k];//NO NEW VALUE SO JUST RETURN THE CURRENT VALUE
              }
          } else {
              return;
          }
      }
      return _o;
  };

}

Damit können Sie auch einen Wert festlegen!

Ich habe eine npm-Paket y github auch damit

0voto

ayushgp Punkte 4365

Die Lösungen hier sind nur für den Zugriff auf die tief verschachtelten Schlüssel. Ich brauchte eine Lösung für den Zugriff auf die Schlüssel sowie für das Hinzufügen, Ändern und Löschen von Schlüsseln. Das habe ich mir ausgedacht:

var deepAccessObject = function(object, path_to_key, type_of_function, value){
    switch(type_of_function){
        //Add key/modify key
        case 0: 
            if(path_to_key.length === 1){
                if(value)
                    object[path_to_key[0]] = value;
                return object[path_to_key[0]];
            }else{
                if(object[path_to_key[0]])
                    return deepAccessObject(object[path_to_key[0]], path_to_key.slice(1), type_of_function, value);
                else
                    object[path_to_key[0]] = {};
            }
            break;
        //delete key
        case 1:
            if(path_to_key.length === 1){
                delete object[path_to_key[0]];
                return true;
            }else{
                if(object[path_to_key[0]])
                    return deepAccessObject(object[path_to_key[0]], path_to_key.slice(1), type_of_function, value);
                else
                    return false;
            }
            break;
        default:
            console.log("Wrong type of function");
    }
};
  • path_to_key : Pfad in einem Array. Sie können ihn durch Ihren string_path.split(".") .
  • type_of_function : 0 für den Zugriff (übergeben Sie keinen Wert an value ), 0 für Hinzufügen und Ändern. 1 für löschen.

0voto

Jonan Gueorguiev Punkte 1009

Wie wäre es mit dieser Lösung?

setJsonValue: function (json, field, val) {
  if (field !== undefined){
    try {
      eval("json." + field + " = val");
    }
    catch(e){
      ;
    }
  }  
}

Und das hier, um es zu bekommen:

getJsonValue: function (json, field){
  var value = undefined;
  if (field !== undefined) {
    try {
      eval("value = json." + field);
    } 
    catch(e){
      ;
    }
  }
  return value;
};

Wahrscheinlich werden einige sie für unsicher halten, aber sie müssen viel schneller sein als das Parsen der Zeichenkette.

1 Stimmen

+1, Dies ist eine absolut gültige Antwort, wenn die Leistung wichtig ist und Sie die Getter-Funktionen im Voraus erstellen und garantieren können, dass die Zeichenfolgen sicher sind. Obwohl ich verwenden würde new Function die etwas sicherer ist, da sie nicht auf Variablen außerhalb ihres Geltungsbereichs zugreifen kann. Wir sprechen hier von einer 10-fachen Geschwindigkeit pro Lookup.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X