Untuk beberapa alasan saya tidak dapat menemukan hal sederhana ini di dokumen MDN (mungkin saya melewatkannya).
Saya berharap ini berhasil:
const map = new Map({foo: 'bar'});
map.get('foo'); // 'bar'
... tapi baris pertama melempar TypeError: (var)[Symbol.iterator] is not a function
Bagaimana cara membuat Peta dari objek biasa? Apakah saya benar-benar harus mengonversinya terlebih dahulu menjadi array array pasangan kunci-nilai?
javascript
ecmascript-6
callum
sumber
sumber
Object.entries
benar-benar pendekatan yang lebih baikObject.keys
, dan pendekatan fungsi generator bergi sedikit lebih langsung daripadaObject.keys
atauObject.entries
.Jawaban:
Ya,
Map
konstruktor mengambil larik pasangan nilai kunci.Object.entries
adalah metode statis Objek baru yang tersedia di ES2017 (19.1.2.5) .Saat ini diterapkan di Firefox 46+ dan Edge 14+ dan versi Chrome yang lebih baru
Jika Anda perlu mendukung lingkungan lama dan transpilasi bukanlah pilihan untuk Anda, gunakan polyfill, seperti yang direkomendasikan oleh georg:
sumber
Object.entries = obj => Object.keys(obj).map(k => [k, obj[k]])
Object.entries
mendarat di Node 7.x tepat (tanpa bendera) btwSilakan lihat jawaban nils menggunakan
Object.entries
dan / atau jawaban bergi menggunakan fungsi generator . MeskipunObject.entries
belum ada dalam spesifikasi ketika pertanyaan diajukan, itu berada di Tahap 4 , jadi aman untuk melakukan polyfill dan digunakan bahkan pada bulan April 2016 (hanya). (Lebih lanjut tentang tahapan di sini .) Dan fungsi generator ada di ES2015. OP secara khusus diminta untuk menghindari perantara, dan sementara generator tidak sepenuhnya menghindarinya, ia melakukan pekerjaan yang lebih baik daripada di bawah atau (sedikit)Object.enties
.FWIW, menggunakan
Object.entries
:[name, value]
larik untuk diteruskannew Map
Map
konstruktor memanggil fungsi pada array untuk mendapatkan iterator; array membuat dan mengembalikan objek interator array.Map
penggunaan konstruktor bahwa objek iterator untuk mendapatkan entri (dalam[name, value]
array) dan membangun petaMenggunakan generator:
Map
konstruktor memanggil fungsi pada objek generator untuk mendapatkan iterator dari itu; objek generator mengembalikan dirinya sendiriMap
konstruktor menggunakan objek Generator (sebagai iterator) untuk mendapatkan entri (dalam[name, value]
array) dan membangun petaJadi: Satu perantara lebih sedikit (array dari
Object.entries
).Namun, menggunakan
Object.entries
lebih sederhana dan membuat array itu tidak menjadi masalah 99,999% dari waktu. Jadi sungguh, salah satunya. Tapi keduanya lebih baik dari yang di bawah. :-)Jawaban asli:
Untuk menginisialisasi a
Map
, Anda dapat menggunakan iterator apa pun yang mengembalikan pasangan kunci / nilai sebagai array, seperti array array:Tidak ada konversi bawaan dari objek ke peta, tetapi itu mudah dilakukan dengan
Object.keys
:Anda bisa, tentu saja, memberi diri Anda fungsi pekerja untuk mengatasinya:
Kemudian
Atau inilah versi yang lebih mirip l33t (apakah itu masih ada?):
(Ya,
Map#set
mengembalikan referensi peta. Beberapa berpendapat ini merupakan abusage darireduce
.)Atau kita benar - benar bisa berlebihan dalam ketidakjelasan:
Tidak, saya tidak akan pernah melakukan itu secara nyata. :-)
sumber
var buildMap2 = o => new Map(Object.keys(o).map(k => [k, o[k]]));
.new Map(Object.entries(object))
stackoverflow.com/a/36644558/798133Tidak, iterator dari array pasangan nilai-kunci sudah cukup. Anda dapat menggunakan berikut ini untuk menghindari pembuatan array perantara:
sumber
if(!obj.hasOwnProperties(key)) continue;
tepat setelah kondisi perulangan for untuk memastikan bahwa Anda tidak menghasilkan properti yang diwarisi dari prototipe objek (kecuali Anda mempercayai objek tersebut, tetapi harus melakukannya kapan saja saat iterasi objek menggunakanin
sebagai kebiasaan yang baik)..hasOwnProperty
propertinya juga, dan Anda harus menggunakannyaObject.prototype.hasOwnProperty.call(obj, key)
call
. Semua konvensi di luar sana yang merekomendasikanobj.hasOwnProperties(key)
tampaknya tidak tahu apa yang mereka lakukan.Object
menjadiMap
operasi yang mahal dan OP secara khusus meminta solusi tanpa perantara. Jadi mengapa ini bukan jawaban yang dikecualikan? Nah, menanyakan ini mungkin sia-sia, itu hanya mengganggu saya.function* entries<T>(obj: T): Generator<readonly [keyof T, T[keyof T]]> {…}
. Jugayield [key, obj[key]] as const;
akan membantu TypeScript menyadari bahwa itu menghasilkan tupel, bukan array.Jawaban oleh Nils menjelaskan bagaimana mengubah objek menjadi peta, yang menurut saya sangat berguna. Namun, OP juga bertanya-tanya di mana informasi ini ada di dokumen MDN. Meskipun mungkin tidak ada di sana ketika pertanyaan awalnya ditanyakan, sekarang ada di halaman MDN untuk Object.entries () di bawah judul Mengonversi Objek ke Peta yang menyatakan:
sumber
sumber
var buildMap2 = o => new Map(Object.keys(o).map(k => [k, o[k]]));
.Alternatifnya Anda bisa menggunakan metode lodash toPairs :
sumber
ES6
konversi objek ke peta:
konversikan peta menjadi objek:
Catatan: fungsi mapToObj mengasumsikan kunci peta adalah string (akan gagal jika tidak)
sumber
Dengan bantuan beberapa JQuery,
sumber