2016-05-04 7 views
1

Ich habe bereits einige der Antworten auf solche Frage überprüft, jedoch möchte ich meine Frage anders stellen.Überprüfen der Existenz verschachtelter Eigenschaft in einem Objekt Javascript

Können sagen, wir haben eine Zeichenfolge wie: „level1.level2.level3 ...“ die in einem Objekt namens Obj eine verschachtelte Eigenschaft gibt.

Der Punkt ist, dass wir können nicht wissen, dass wie viele verschachtelte Eigenschaften in dieser Zeichenfolge vorhanden sind. Zum Beispiel kann es "level1.level2" oder "level1.level2.level3.level4" sein.

Jetzt möchte ich eine Funktion, die die Obj und die Zeichenfolge der Eigenschaften als Eingabe, einfach sagen uns, ob eine solche verschachtelte Eigenschaft im Objekt vorhanden ist oder nicht (sagen wir wahr oder falsch als Ausgabe).


Update: Dank @Silvinus, ich habe die Lösung mit einer kleinen Modifikation gefunden:

 private checkNestedProperty(obj, props) { 
     var splited = props.split('.'); 
     var temp = obj; 
     for (var index in splited) { 
      if (temp[splited[index]] === 'undefined' || !temp[splited[index]]) return false; 
      temp = temp[splited[index]]; 
     } 
     return true; 
    } 
+0

@Pedram, wollen Sie "Bericht" über Existenz jeder Eigenschaft oder nur für die meisten (letzten) geschachtelten erhalten? – RomanPerekhrest

+0

@RomanPerekhrest In der Tat die meisten (letzten). Es ist jedoch offensichtlich, dass, wenn jede dieser Eigenschaften nicht existiert, die letzte nicht existiert :) – Pedram

+0

Ich wundere mich, warum meine Frage eine Abstimmung unten erhalten sollte! – Pedram

Antwort

3

Sie können Ihre Obj mit dieser Funktion erkunden:

var fn = function(obj, props) { 
     var splited = props.split('.'); 
     var temp = obj; 
     for(var index in splited) { 
      if(typeof temp[splited[index]] === 'undefined') return false; 
      temp = temp[splited[index]] 
     } 
      return true 
     } 

var result = fn({ }, "toto.tata"); 
console.log(result); // false 

var result = fn({ toto: { tata: 17 } }, "toto.tata"); 
console.log(result); // true 

var result = fn({ toto: { tata: { tutu: 17 } } }, "toto.foo.tata"); 
console.log(result); // false 

Diese Funktion ermöglicht verschachtelte Eigenschaft Obj zu erforschen, die vergangen Requisiten hängt in Parameter

+0

Diese Antwort scheitert an der Groß-/Kleinschreibung 'fn ({a: false}, 'a')' '. Kleiner Punkt, aber die Variable 'temp' ist hier nicht notwendig. –

+0

Außerdem sollte es nicht 'temp = temp [zerlegt [index]];'? Aus diesem Grund verursacht der Testfall 'fn ({a: {b: {c: 1}}}, 'a.b.c')' einen Laufzeitfehler "Eigenschaft 'c' von undefined kann nicht gelesen werden". –

+0

Für den ersten Kommentar, ... stimme ich zu. Ich schreibe diesen Code so schnell. Ich habe es bearbeitet und ändere meinen Test um if (typeof temp [zerlegt [index]] === 'undefiniert') return false; Für die zweite, tut mir leid, es ist ein Fehler. temp = obj [geteilter [index]] muss ersetzt werden durch temp = temp [geteilter [index]] – Silvinus

1

This answer die grundlegende Antwort auf Ihre Frage stellt. Aber es muss optimiert werden, die den undefinierten Fall zu behandeln:

function isDefined(obj, path) { 
    function index(obj, i) { 
    return obj && typeof obj === 'object' ? obj[i] : undefined; 
    } 

    return path.split(".").reduce(index, obj) !== undefined; 
} 
+0

Warum runterzählen? Downvoter, wie wäre es mit einer Erklärung ?! Oder vielleicht klicken Sie einfach ohne Argumente? – RomanPerekhrest

2

Sie könnten Array#every() und thisArg davon verwenden, indem Sie die Schlüssel durchlaufen und prüfen, ob es in dem gegebenen Objekt ist.

var fn = function (obj, props) { 
 
    return props.split('.').every(function (k) { 
 
     if (k in this.o) { 
 
      this.o = this.o[k]; 
 
      return true; 
 
     } 
 
    }, { o: obj }); 
 
} 
 

 
document.write(fn({}, "toto.tata") + '<br>');         // false 
 
document.write(fn({ toto: { tata: 17 } }, "toto.tata") + '<br>');    // true 
 
document.write(fn({ toto: { tata: { tutu: 17 } } }, "toto.foo.tata") + '<br>'); // false

0

Basierend auf der Lösung von @Silvinus gegeben ist hier eine Lösung, wenn Sie mit Array innerhalb verschachtelten Objekten beschäftigen (wie es oft der Fall in den Ergebnissen aus Datenbanken Abfragen ist):

checkNested = function(obj, props) { 
    var splited = props.split('.'); 
    var temp = obj; 
    for(var index in splited) { 
     var regExp = /\[([^)]+)\]/; 
     var matches = regExp.exec(splited[index]) 
     if(matches) { 
     splited[index] = splited[index].replace(matches[0], ''); 
     } 
     if(matches) { 
     if(matches && typeof temp[splited[index]][matches[1]] === 'undefined') return false; 
      temp = temp[splited[index]][matches[1]]; 
     } 
     else { 
      if(!matches && typeof temp[splited[index]] === 'undefined') return false; 
       temp = temp[splited[index]] 
     } 
    } 
    return true 
} 

obj = {ok: {ao: [{},{ok: { aa: ''}}]}} 

console.log(checkNested(obj, 'ok.ao[1].ok.aa')) // ==> true 
console.log(checkNested(obj, 'ok.ao[0].ok.aa')) // ==> false 
Verwandte Themen