Mam taką strukturę danych:
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'
}
]
};
I chciałbym uzyskać dostęp do danych przy użyciu tych zmiennych:
var part1name = "part1.name";
var part2quantity = "part2.qty";
var part3name1 = "part3[0].name";
part1name powinna być wypełniona someObject.part1.name
wartością, czyli „Part 1”. To samo z part2quantity, który wypełniał 60.
Czy można to osiągnąć za pomocą czystego javascript lub JQuery?
javascript
jquery
path
nested
Komaruloh
źródło
źródło
var part1name = someObject.part1name;
`Odpowiedzi:
Właśnie stworzyłem to w oparciu o jakiś podobny kod, który już miałem, wygląda na to, że działa:
Stosowanie::
Zobacz działające demo na http://jsfiddle.net/alnitak/hEsys/
EDIT niektórzy zauważyli, że ten kod zgłosi błąd, jeśli przekaże ciąg, w którym indeksy najbardziej po lewej stronie nie odpowiadają poprawnie zagnieżdżonej pozycji w obiekcie. Jest to ważna kwestia, ale IMHO najlepiej rozwiązywać za pomocą
try / catch
bloku podczas wywoływania, zamiast tego, aby ta funkcja cicho zwracałaundefined
niepoprawny indeks.źródło
_.get(object, nestedPropertyString);
'part3[0].name.iDontExist'
. Dodanie zaznaczenia, aby sprawdzić, czyo
jest obiektem wif in
rozwiązuje problem. (To, jak sobie poradzisz, zależy od ciebie). Zobacz zaktualizowane skrzypce: jsfiddle.net/hEsys/418Oto rozwiązanie, którego używam:
Przykładowe użycie:
Ograniczenia:
[]
) do indeksów tablic - chociaż określenie indeksów tablic między tokenem separatora (np..
) Działa dobrze, jak pokazano powyżej.źródło
_.reduce()
z biblioteki podkreślenia lub biblioteki lodash)self
prawdopodobnie nie jest tutaj zdefiniowany. Czy masz na myślithis
?Jest to teraz obsługiwane przez lodash przy użyciu
_.get(obj, property)
. Zobacz https://lodash.com/docs#getPrzykład z dokumentów:
źródło
_.set(...)
_.get
pokaże takie samo zachowanie, jak wtedy, gdy w podanym obiekcie nie zostanie znaleziony żaden klucz. np_.get(null, "foo") -> undefined
,_.get(null, "foo", "bar") -> "bar"
. Jednak to zachowanie nie jest zdefiniowane w dokumentacji, więc może ulec zmianie.ES6 : Tylko jedna linia w Vanila JS (zwraca null, jeśli nie znajduje zamiast błędu):
Lub przykład:
W przypadku gotowej do użycia funkcji, która rozpoznaje również fałsz, 0 i liczbę ujemną i przyjmuje wartości domyślne jako parametr:
Przykład użycia:
Bonus :
Aby ustawić ścieżkę (wymagane przez @ rob-gordon), możesz użyć:
Przykład:
Dostęp do tablicy za pomocą [] :
Przykład:
źródło
let o = {a:{b:{c:1}}}; let str = 'a.b.c'; str.split('.').splice(0, str.split('.').length - 1).reduce((p,c)=>p&&p[c]||null, o)[str.split('.').slice(-1)] = "some new value";
0
,undefined
anull
wartości.{a:{b:{c:0}}}
zwracanull
zamiast0
. Być może jawne sprawdzenie wartości null lub niezdefiniowanej rozwiąże te problemy.(p,c)=>p === undefined || p === null ? undefined : p[c]
Reflect.has(o, k) ? ...
(ES6 Reflect.has )setPath
ustawi wartość przy pierwszym wystąpieniu ostatniego selektora. Na przykładlet o = {}; setPath(o, 'a.a', 0)
wyniki{a: 0}
zamiast{a: {a: 0}}
. zobacz ten post dla rozwiązania.Musisz sam parsować ciąg:
Wymagało to również zdefiniowania indeksów tablic z notacją kropkową:
Ułatwia to analizę.
PRÓBNY
źródło
[]
składni na składnię właściwości jest dość trywialna.while (l > 0 && (obj = obj[current]) && i < l)
ten kod działa również dla ciągów bez kropek.Działa również dla tablic / tablic wewnątrz obiektu. Obrona przed nieprawidłowymi wartościami.
źródło
przy użyciu eval:
zawiń, aby zwrócić niezdefiniowane po błędzie
http://jsfiddle.net/shanimal/b3xTw/
Korzystając z mocy evalu, zachowaj zdrowy rozsądek i ostrożność. To trochę jak lekka szabla, jeśli ją włączysz, masz 90% szansy na rozerwanie kończyny. To nie jest dla wszystkich.
źródło
Możesz uzyskać wartość elementu głębokiego obiektu z notacją kropkową bez żadnej zewnętrznej biblioteki JavaScript za pomocą prostej sztuczki:
W twoim przypadku, aby uzyskać wartość
part1.name
odsomeObject
po prostu zrób:Oto proste demo skrzypce: https://jsfiddle.net/harishanchu/oq5esowf/
źródło
Prawdopodobnie nigdy nie ujrzy światła dziennego ... ale i tak jest.
[]
składnię nawiasu na.
.
postaćundefined
)źródło
Jest to jedna wkładka z lodash.
A nawet lepiej ...
Lub wersja ES6 w / zmniejsz ...
Plunkr
źródło
Myślę, że o to prosisz:
Możesz o to poprosić:
Oba będą działać
A może o to prosisz
Wreszcie możesz o to poprosić
źródło
Split
metody, ale raczejsplit
.Tutaj oferuję więcej sposobów, które pod wieloma względami wydają się szybsze:
Opcja 1: Podziel ciąg na. lub [lub] lub „lub”, odwróć, pomiń puste elementy.
Opcja 2 (najszybsza ze wszystkich, z wyjątkiem
eval
): skanowanie znaków niskiego poziomu (brak wyrażeń regularnych / split / etc, tylko szybki skan znaków). Uwaga: Ten nie obsługuje cudzysłowów dla indeksów.Opcja 3: ( nowa : opcja 2 rozszerzona o obsługę cytatów - nieco wolniej, ale nadal szybko)
JSPerf: http://jsperf.com/ways-to-dereference-a-delimited-property-string/3
„eval (...)” jest jednak nadal królem (pod względem wydajności). Jeśli masz ścieżki właściwości bezpośrednio pod kontrolą, nie powinno być żadnych problemów z używaniem „eval” (szczególnie, jeśli pożądana jest prędkość). Jeśli ciągnąc ścieżki własności „nad drutem” ( na linii !? Lol: P), to tak, użyj czegoś innego, aby być bezpiecznym. Tylko idiota powiedziałby, aby w ogóle nigdy nie używać „ewaluacji”, ponieważ istnieją dobre powody , aby z niego korzystać. Ponadto: „Jest używany w parserze JSON Douga Crockforda ”. Jeśli wejście jest bezpieczne, nie ma żadnych problemów. Użyj odpowiedniego narzędzia do właściwej pracy, to wszystko.
źródło
Na wszelki wypadek, gdy ktoś odwiedza to pytanie w 2017 roku lub później i szuka łatwego do zapamiętania sposobu, oto skomplikowany post na blogu na temat uzyskiwania dostępu do obiektów zagnieżdżonych w JavaScript bez przeszkadzania przez
Nie można odczytać właściwości „foo” niezdefiniowanego błędu
Uzyskaj dostęp do zagnieżdżonych obiektów za pomocą funkcji Array Reduce
Weźmy tę przykładową strukturę
Aby mieć dostęp do zagnieżdżonych tablic, możesz napisać własną tablicę, zmniejsz wykorzystanie.
Istnieje również doskonały typ obsługujący minimalne typy bibliotek, który robi to wszystko za Ciebie.
W przypadku typów Twój kod będzie wyglądał następująco
Uwaga: Jestem autorem tego pakietu.
źródło
AngularJS
Podejście Speigga jest bardzo schludne i czyste, chociaż znalazłem tę odpowiedź, szukając rozwiązania dostępu do właściwości zakresu AngularJS $ po ścieżce łańcucha i przy niewielkiej modyfikacji wykonuje to zadanie:
Po prostu umieść tę funkcję w kontrolerze głównym i użyj dowolnego podrzędnego zakresu:
źródło
$scope.$eval
inny sposób na zrobienie tego z AngularJS.Nie znalazłem jeszcze pakietu do wykonania wszystkich operacji ze ścieżką łańcuchową, więc skończyłem pisać własny szybki pakiet, który obsługuje insert (), get () (z domyślnym zwrotem), set () i remove ( ) operacji.
Możesz używać notacji kropkowej, nawiasów, indeksów liczb, właściwości numerów i kluczy ze znakami innymi niż słowo. Proste użycie poniżej:
https://www.npmjs.com/package/jsocrud
https://github.com/vertical-knowledge/jsocrud
źródło
Pracuje z
źródło
Prosta funkcja, pozwalająca na użycie ciągu znaków lub ścieżki tablicy.
LUB
źródło
Jest
npm
moduł teraz robi to: https://github.com/erictrinh/safe-accessPrzykładowe użycie:
źródło
Chociaż redukcja jest dobra, jestem zaskoczony, że nikt nie używał
Test
źródło
a.b.c
zgłosi wyjątek, jeśli obiekt nie ma właściwościb
. Jeśli potrzebujesz czegoś po cichu odrzucając niewłaściwy keypath (którego nie polecam), nadal możesz zastąpić forEach tymkeys.forEach((key)=> obj = (obj||{})[key]);
Niedawno miałem to samo pytanie i z powodzeniem zastosowałem https://npmjs.org/package/tea-properties, które również
set
zagnieżdżały obiekt / tablice:dostać:
zestaw:
źródło
Zainspirowany odpowiedzią @ webjay: https://stackoverflow.com/a/46008856/4110122
Zrobiłem tę funkcję, której można użyć do uzyskania / ustawienia / rozbrojenia dowolnej wartości w obiekcie
Aby go użyć:
źródło
Rozwijam sklep internetowy z React. Próbowałem zmienić wartości w skopiowanym obiekcie stanu, aby zaktualizować pierwotny stan przy przesyłaniu. Powyższe przykłady nie działały dla mnie, ponieważ większość z nich mutuje strukturę kopiowanego obiektu. Znalazłem działający przykład funkcji dostępu i zmiany wartości właściwości głęboko zagnieżdżonego obiektu: https://lowrey.me/create-an-object-by-path-in-javascript-2/ Oto:
źródło
Na podstawie odpowiedzi Alnitaka .
Owinęłam poliolek w kratkę i zredukowałem tę funkcję do pojedynczej redukcji łańcuchowej.
źródło
Jeśli chcesz uzyskać dostęp do innego zagnieżdżonego klucza, nie wiedząc o tym w czasie kodowania (adresowanie go będzie trywialne), możesz użyć akcesorium notacji tablicowej:
Odpowiadają one akcesorium notacji kropkowej i mogą się różnić w czasie wykonywania, na przykład:
jest równa
lub
Mam nadzieję, że rozwiąże to twoje pytanie ...
EDYTOWAĆ
Nie będę używać ciągu znaków do zarządzania rodzajem zapytania xpath w celu uzyskania dostępu do wartości obiektu. Ponieważ musisz wywołać funkcję, aby przeanalizować zapytanie i pobrać wartość, wybrałbym inną ścieżkę (nie:
lub jeśli nie masz pewności co do metody zastosuj
Funkcje są krótsze, wyraźniejsze, interpreter sprawdza je pod kątem błędów składniowych i tak dalej.
Nawiasem mówiąc, czuję, że proste zadanie wykonane we właściwym czasie będzie wystarczające ...
źródło
Rozwiązania tutaj są tylko dla dostępu do głęboko zagnieżdżonych kluczy. Potrzebowałem jednego do uzyskiwania dostępu, dodawania, modyfikowania i usuwania kluczy. Oto co wymyśliłem:
path_to_key
: ścieżka w tablicy. Możesz go zastąpić swoimstring_path.split(".")
.type_of_function
: 0 za dostęp (nie przekazuj żadnej wartościvalue
), 0 za dodawanie i modyfikowanie. 1 do usunięcia.źródło
Opierając się na odpowiedzi Alnitaka:
}
Pozwala to również ustawić wartość!
I utworzeniu pakietu npm i GitHub z tego, jak dobrze
źródło
Zamiast ciągu można zastosować tablicę adresującą zagnieżdżone obiekty i tablice, np .:
["my_field", "another_field", 0, "last_field", 10]
Oto przykład, który zmieniłby pole w oparciu o tę reprezentację tablicy. Korzystam z czegoś takiego w React.js dla kontrolowanych pól wejściowych, które zmieniają stan zagnieżdżonych struktur.
źródło
Na podstawie poprzedniej odpowiedzi stworzyłem funkcję, która może również obsługiwać nawiasy. Ale nie ma w nich kropek z powodu podziału.
źródło
źródło
Praca z
Underscore
„sproperty
lubpropertyOf
:Powodzenia...
źródło