Saya memiliki struktur data seperti ini:
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'
}
]
};
Dan saya ingin mengakses data menggunakan variabel ini:
var part1name = "part1.name";
var part2quantity = "part2.qty";
var part3name1 = "part3[0].name";
part1name harus diisi dengan someObject.part1.name
nilai, yaitu "Bagian 1". Hal yang sama dengan part2quantity yang diisi dengan 60.
Apakah ada cara untuk mencapai ini dengan javascript murni atau JQuery?
javascript
jquery
path
nested
Komaruloh
sumber
sumber
var part1name = someObject.part1name;
`Jawaban:
Saya baru saja membuat ini berdasarkan pada beberapa kode serupa yang sudah saya miliki, tampaknya berfungsi:
Pemakaian::
Lihat demo yang berfungsi di http://jsfiddle.net/alnitak/hEsys/
EDIT beberapa telah memperhatikan bahwa kode ini akan menimbulkan kesalahan jika melewati string di mana indeks paling kiri tidak sesuai dengan entri bersarang dengan benar dalam objek. Ini adalah masalah yang valid, tetapi IMHO paling baik diatasi dengan
try / catch
blok saat memanggil, daripada meminta fungsi ini diam-diam mengembalikanundefined
indeks yang tidak valid.sumber
_.get(object, nestedPropertyString);
'part3[0].name.iDontExist'
. Menambahkan tanda centang untuk melihat apakaho
ada objek dalamif in
perbaikan masalah. (Bagaimana Anda melakukannya, itu terserah Anda). Lihat biola diperbarui: jsfiddle.net/hEsys/418Ini adalah solusi yang saya gunakan:
Contoh penggunaan:
Keterbatasan:
[]
) untuk indeks array — meskipun menentukan indeks array antara token pemisah (misalnya,.
) berfungsi dengan baik seperti yang ditunjukkan di atas.sumber
_.reduce()
dari garis bawah atau perpustakaan lodash)self
mungkin tidak terdefinisi di sini. Apakah yang Anda maksudthis
?Ini sekarang didukung oleh penggunaan Lodash
_.get(obj, property)
. Lihat https://lodash.com/docs#getContoh dari dokumen:
sumber
_.set(...)
_.get
akan menunjukkan perilaku yang sama seperti ketika tidak ada kunci yang ditemukan di objek yang disediakan. misalnya_.get(null, "foo") -> undefined
,_.get(null, "foo", "bar") -> "bar"
. Namun perilaku ini tidak didefinisikan dalam dokumen sehingga dapat berubah.ES6 : Hanya satu baris di Vanila JS (ini mengembalikan nol jika tidak menemukan alih-alih memberikan kesalahan):
Atau contoh:
Dengan operator rantai opsional :
Untuk fungsi siap pakai yang juga mengenali angka false, 0 dan negatif dan menerima nilai default sebagai parameter:
Contoh untuk digunakan:
Bonus :
Untuk mengatur jalur (Diminta oleh @ rob-gordon) Anda dapat menggunakan:
Contoh:
Array akses dengan [] :
Contoh:
sumber
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
dannull
nilainya.{a:{b:{c:0}}}
mengembalikannull
bukan0
. Mungkin secara eksplisit memeriksa nol atau tidak terdefinisi akan menyelesaikan masalah ini.(p,c)=>p === undefined || p === null ? undefined : p[c]
Reflect.has(o, k) ? ...
(ES6 Reflect.has ) bekerjasetPath
akan menetapkan nilai pada kemunculan pertama pemilih terakhir. Misalnyalet o = {}; setPath(o, 'a.a', 0)
menghasilkan{a: 0}
daripada{a: {a: 0}}
. lihat posting ini untuk solusinya.Anda harus mengurai senar sendiri:
Ini mengharuskan Anda juga mendefinisikan indeks array dengan notasi titik:
Itu membuat parsing lebih mudah.
DEMO
sumber
[]
sintaks ke sintaksis properti cukup sepele.while (l > 0 && (obj = obj[current]) && i < l)
maka kode ini berfungsi untuk string tanpa titik juga.Berfungsi untuk array / array di dalam objek juga. Bertahan terhadap nilai yang tidak valid.
sumber
menggunakan eval:
bungkus untuk mengembalikan yang tidak ditentukan pada kesalahan
http://jsfiddle.net/shanimal/b3xTw/
Silakan gunakan akal sehat dan kehati-hatian ketika menggunakan kekuatan eval. Ini agak seperti pedang cahaya, jika Anda menyalakannya ada kemungkinan 90% Anda akan memutuskan anggota tubuh. Ini bukan untuk semua orang.
sumber
Anda dapat mengatur untuk mendapatkan nilai anggota objek yang dalam dengan notasi titik tanpa pustaka JavaScript eksternal dengan trik sederhana berikut ini:
Dalam kasus Anda untuk memperoleh nilai
part1.name
darisomeObject
hanya melakukan:Berikut ini adalah demo biola sederhana: https://jsfiddle.net/harishanchu/oq5esowf/
sumber
Ini mungkin tidak akan pernah melihat cahaya hari ... tapi ini dia.
[]
sintaks braket dengan.
.
karakterundefined
)sumber
Ini satu liner dengan lodash.
Atau bahkan lebih baik ...
Atau versi ES6 dengan / ...
Plunkr
sumber
Saya pikir Anda meminta ini:
Anda bisa meminta ini:
Keduanya akan bekerja
Atau mungkin Anda meminta ini
Akhirnya Anda bisa meminta ini
sumber
Split
metode, melainkansplit
.Di sini saya menawarkan lebih banyak cara, yang tampaknya lebih cepat dalam banyak hal:
Opsi 1: Split string aktif. atau [atau] atau 'atau ", balikkan, lewati item kosong.
Opsi 2 (kecuali yang tercepat
eval
): Pemindaian karakter tingkat rendah (tanpa regex / split / dll, hanya pemindaian karakter cepat). Catatan: Yang ini tidak mendukung kutipan untuk indeks.Opsi 3: ( baru : opsi 2 diperluas untuk mendukung kutipan - sedikit lebih lambat, tetapi masih cepat)
JSPerf: http://jsperf.com/ways-to-dereference-a-delimited-property-string/3
"eval (...)" masih tetap raja (kinerja bijaksana yaitu). Jika Anda memiliki jalur properti langsung di bawah kendali Anda, seharusnya tidak ada masalah dengan menggunakan 'eval' (terutama jika kecepatan diinginkan). Jika menarik jalur properti "di atas kabel" ( di telepon !? Lol: P), maka ya, gunakan sesuatu yang lain agar aman. Hanya seorang idiot yang akan mengatakan untuk tidak pernah menggunakan "eval" sama sekali, karena ADA alasan bagus untuk menggunakannya. Juga, "Ini digunakan dalam parser JSON Doug Crockford ." Jika inputnya aman, maka tidak ada masalah sama sekali. Gunakan alat yang tepat untuk pekerjaan yang tepat, itu saja.
sumber
Untuk jaga-jaga, siapa pun yang mengunjungi pertanyaan ini pada 2017 atau lebih baru dan mencari cara yang mudah diingat , berikut ini adalah posting blog yang rumit tentang Mengakses Objek Bersarang di JavaScript tanpa dikacaukan oleh
Tidak dapat membaca properti 'foo' yang tidak terdefinisi kesalahan yang
Akses Objek Bersarang Menggunakan Array Reduce
Mari kita ambil contoh struktur ini
Untuk dapat mengakses array bersarang, Anda dapat menulis util pengurangan array Anda sendiri.
Ada juga jenis penanganan perpustakaan typy yang sangat baik yang yang melakukan semua ini untuk Anda.
Dengan typy, kode Anda akan terlihat seperti ini
Penafian: Saya pembuat paket ini.
sumber
AngularJS
Pendekatan Speigg sangat rapi dan bersih, meskipun saya menemukan balasan ini ketika mencari solusi untuk mengakses properti lingkup AngularJS $ melalui jalur string dan dengan sedikit modifikasi ia bekerja:
Cukup tempatkan fungsi ini di pengontrol root Anda dan gunakan setiap lingkup anak seperti ini:
sumber
$scope.$eval
cara lain untuk melakukannya dengan AngularJS.Saya belum menemukan paket untuk melakukan semua operasi dengan jalur string, jadi saya akhirnya menulis paket kecil cepat saya sendiri yang mendukung insert (), get () (dengan pengembalian default), set () dan hapus ( ) operasi.
Anda dapat menggunakan notasi titik, tanda kurung, indeks angka, properti nomor string, dan kunci dengan karakter non-kata. Penggunaan sederhana di bawah ini:
https://www.npmjs.com/package/jsocrud
https://github.com/vertical-knowledge/jsocrud
sumber
Bekerja dengan
sumber
Fungsi sederhana, memungkinkan untuk jalur string atau array.
ATAU
sumber
Ada
npm
modul sekarang untuk melakukan ini: https://github.com/erictrinh/safe-accessContoh penggunaan:
sumber
Meskipun mengurangi baik, saya terkejut tidak ada yang menggunakan forEach:
Uji
sumber
a.b.c
akan memunculkan pengecualian jika tidak ada propertib
di objek Anda. Jika Anda perlu sesuatu secara diam-diam mengabaikan keypath yang salah (yang tidak saya sarankan), Anda masih bisa mengganti forEach dengan yang satu inikeys.forEach((key)=> obj = (obj||{})[key]);
Baru saja memiliki pertanyaan yang sama baru-baru ini dan berhasil menggunakan https://npmjs.org/package/tea-properties yang juga
set
menyarangkan objek / array:Dapatkan:
set:
sumber
Terinspirasi oleh jawaban webjay: https://stackoverflow.com/a/46008856/4110122
Saya membuat fungsi ini yang dapat Anda gunakan untuk Get / Set / Unset nilai apa pun di objek
Untuk menggunakannya:
sumber
Saya mengembangkan toko online dengan React. Saya mencoba untuk mengubah nilai dalam objek keadaan disalin untuk memperbarui keadaan asli dengan itu pada saat mengirimkan. Contoh di atas tidak berhasil untuk saya, karena kebanyakan dari mereka bermutasi struktur objek yang disalin. Saya menemukan contoh kerja dari fungsi untuk mengakses dan mengubah nilai properti objek bersarang mendalam: https://lowrey.me/create-an-object-by-path-in-javascript-2/ Ini dia:
sumber
Berdasarkan jawaban Alnitak .
Saya membungkus polyfill dalam cek, dan mengurangi fungsinya menjadi reduksi berantai tunggal.
sumber
Jika Anda perlu mengakses kunci bersarang yang berbeda tanpa mengetahuinya pada waktu pengkodean (itu akan sepele untuk mengatasinya) Anda dapat menggunakan accessor notasi array:
Mereka setara dengan accessor notasi titik dan dapat bervariasi saat runtime, misalnya:
setara dengan
atau
Saya harap ini menjawab pertanyaan Anda ...
EDIT
Saya tidak akan menggunakan string untuk mempertahankan semacam permintaan xpath untuk mengakses nilai objek. Karena Anda harus memanggil fungsi untuk mengurai kueri dan mengambil nilai, saya akan mengikuti jalur lain (tidak:
atau, jika Anda tidak nyaman dengan metode yang berlaku
Fungsinya lebih pendek, lebih jelas, penerjemah memeriksa Anda untuk kesalahan sintaks dan sebagainya.
Ngomong-ngomong, saya merasa bahwa tugas sederhana yang dibuat pada waktu yang tepat akan cukup ...
sumber
Solusi di sini hanya untuk mengakses kunci yang sangat bersarang. Saya membutuhkan satu untuk mengakses, menambahkan, memodifikasi dan menghapus kunci. Inilah yang saya pikirkan:
path_to_key
: path dalam sebuah array. Anda dapat menggantinya denganstring_path.split(".")
.type_of_function
: 0 untuk mengakses (jangan meneruskan nilai apa pun kevalue
), 0 untuk menambah dan memodifikasi. 1 untuk dihapus.sumber
Membangun dari jawaban Alnitak:
}
Ini memungkinkan Anda untuk menetapkan nilai juga!
Saya telah membuat paket npm dan github dengan ini juga
sumber
Alih-alih sebuah string, sebuah array dapat digunakan untuk memberi alamat objek dan array seperti:
["my_field", "another_field", 0, "last_field", 10]
Berikut adalah contoh yang akan mengubah bidang berdasarkan representasi array ini. Saya menggunakan sesuatu seperti itu di react.js untuk bidang input terkontrol yang mengubah keadaan struktur bersarang.
sumber
Berdasarkan jawaban sebelumnya, saya telah membuat fungsi yang juga dapat menangani tanda kurung. Tapi tidak ada titik di dalamnya karena perpecahan.
sumber
sumber
Bekerja dengan
Underscore
'sproperty
ataupropertyOf
:Semoga berhasil...
sumber