2011-08-02 4 views
19
var arr = { foo : 1, bar: { baz : 2 }, bee : 3 } 

function getter(variable) { 
    return arr[variable]; 
} 

Jeśli chcę „foo” vs „bee” mogę po prostu zrobić arr[variable] - to łatwe, a funkcja robi.W javascript w jaki sposób można dynamicznie uzyskać zagnieżdżonych właściwości obiektu

Ale co, jeśli chcę uzyskać arr.bar.baz AKA arr[bar][baz]?

Co mogę przekazać do funkcji gettera, która pozwoli mi to zrobić (i oczywiście pozwól mi uzyskać właściwości nie zagnieżdżone, używając tej samej funkcji).

Próbowałem getter('bar.baz') i getter('[bar][baz]'), ale te nie działały.

Przypuszczam, że mogę analizować kropki lub nawiasy (jak tutaj: In javascript, test for property deeply nested in object graph?). Czy istnieje czystszy sposób? (Poza eval oczywiście.)

Szczególnie, że muszę uzyskać głęboko ustawione poprawnie wiele razy w pętli na kilka elementów tablicy.

+0

Dlaczego po prostu nie używasz tego podejścia z połączonego pytania? – Shi

+0

Głównie ze względu na narzut wywoływania funkcji tak często, a także jeśli istnieje lepszy sposób, chcę ją poznać. – Ariel

Odpowiedz

9

Jak o zmianie podpis funkcja pobierająca jako getter('bar', 'baz') zamiast

function getter() { 
    var v = arr; 
    for(var i=0; i< arguments.length; i++) { 
    if(!v) return null; 
    v = v[arguments[i]]; 
    } 
    return v; 
} 

ps. nie testowałem, ale masz pomysł;)

1

Możesz uzyskać dostęp do argumentów funkcji, w których możesz przekazać dowolną liczbę ciągów. Polecam również przy użyciu arr jako parametr dla lepszej enkapsulacji:

function getter() { 
    var current = arguments[0]; 
    for(var i = 1; i < arguments.length; i++) { 
     if(current[arguments[i]]) { 
      current = current[arguments[i]]; 
     } else { 
      return null; 
     } 
    } 
    return current; 
} 

var arr = { foo : 1, bar: { baz : 2 }, bee : 3 }; 
var baz = getter(arr, 'bar', 'baz'); 
30

Można użyć funkcji dostępu głęboki opartej na sznurku na ścieżce. Zauważ, że nie możesz mieć żadnych kropek w nazwach właściwości.

function getPropByString(obj, propString) { 
    if (!propString) 
     return obj; 

    var prop, props = propString.split('.'); 

    for (var i = 0, iLen = props.length - 1; i < iLen; i++) { 
     prop = props[i]; 

     var candidate = obj[prop]; 
     if (candidate !== undefined) { 
      obj = candidate; 
     } else { 
      break; 
     } 
    } 
    return obj[props[i]]; 
} 

var obj = {foo: {bar: {baz: 'x'}}}; 

alert(getPropByString(obj, 'foo.bar.baz')); // x 
alert(getPropByString(obj, 'foo.bar.baz.buk')); // undefined 

Jeśli łańcuch dostępu jest pusty, zwraca obiekt. W przeciwnym razie kontynuuje ścieżkę dostępu do drugiego ostatniego akcesora. Jeśli jest to ojbect, zwraca ostatnią wartość object[accessor]. W przeciwnym razie zwraca niezdefiniowane.

1

Theres funkcję zdefiniowaną on this blog bezpiecznie odczytać właściwości zagnieżdżonych z obiektu JS

pozwala wydobywać obiektu dla właściwości ... ie.

safeRead(arr, 'foo', 'bar', 'baz'); 

i jeśli jakakolwiek część łańcucha obiektu jest zerowy lub niezdefiniowane zwraca pusty ciąg ....

12

Stosując metody bibliotecznych lodash byłoby lepsze podejście: - https://lodash.com/docs#get

_.get(arr, 'bar.baz'); //returns 2; 
_.get(arr, 'bar.baz[5].bazzz'); //returns undefined wont throw error; 
_.get(arr, 'bar.baz[5].bazzz', 'defaultvalue'); // Returns defaultValue because result is undefined 
+1

Dziękuję, właśnie tego szukałem. Jego przyjaciel '_.set' jest również bardzo użyteczny. –

0

Niedawno opracowałem własną metodę Object, aby uzyskać właściwość obiektu zagnieżdżoną między obiektami i tablicami niezależnie od tego, jak głęboka jest. Wykorzystuje pojedynczą linię rekursywnego podejścia. Sprawdź to.

Object.prototype.getNestedValue = function(...a) { 
 
    return a.length > 1 ? (this[a[0]] !== void 0 && this[a[0]].getNestedValue(...a.slice(1))) : this[a[0]]; 
 
}; 
 

 
var myObj = { foo : 1, bar: { baz : 2 }, bee : 3 }, 
 
    bazval = myObj.getNestedValue("bar","baz"); 
 

 
document.write(bazval);

Teraz sprawdzić głębiej zagnieżdżonego obiektu tablicy struktury danych kombi

Object.prototype.getNestedValue = function(...a) { 
 
    return a.length > 1 ? (this[a[0]] !== void 0 && this[a[0]].getNestedValue(...a.slice(1))) : this[a[0]]; 
 
}; 
 

 
var myArr = [{fox: [{turn:[857, 432]}]}, {sax: [{pana:[777, 987]}]}, {ton: [{joni:[123, 567]}]}, {piu: [{burn:[666, 37]}]}, {sia: [{foxy:[404, 696]}]}]; 
 
    
 
document.write(myArr.getNestedValue(3,"piu",0,"burn",1));

wierzę mogąc przekazać parametry wyszukiwania dynamicznie do istniejących metod tablicowych wykonywałby akcje takie jak wyszukiwanie, filtrowanie r zastępowanie głęboko zagnieżdżonych struktur jest bardzo łatwe.

Powiązane problemy