Katakanlah saya punya objek:
elmo = {
color: 'red',
annoying: true,
height: 'unknown',
meta: { one: '1', two: '2'}
};
Saya ingin membuat objek baru dengan subset propertinya.
// pseudo code
subset = elmo.slice('color', 'height')
//=> { color: 'red', height: 'unknown' }
Bagaimana saya bisa mencapai ini?
javascript
Christian Schlensker
sumber
sumber
emo.slice
pada pandangan pertama.Jawaban:
Menggunakan Destrukturisasi Objek dan Properti
Dari Philipp Kewisch:
sumber
let unwrap = ({a, c}) => ({a, c}); let unwrap2 = function({a, c}) { return { a, c }; }; let picked = unwrap({ a: 5, b: 6, c: 7 });
const { b, ...picked } = object
akan dibuatpicked
sebagai{ a: 5, c: 7 }
. Anda telah menentukan hanya untuk menghapus b. Eslint Anda mungkin akan kesal pada Anda karena menyatakan var yang tidak Anda gunakan.Saya sarankan untuk melihat Lodash ; ia memiliki banyak fungsi utilitas yang luar biasa.
Misalnya
pick()
persis apa yang Anda cari:biola
sumber
_.omit(elmo, ['voice'])
untuk mengembalikan semuanya kecualivoice
Jika Anda menggunakan ES6, ada cara yang sangat ringkas untuk melakukan ini dengan menggunakan penataan. Destrukturisasi memungkinkan Anda untuk dengan mudah menambahkan objek menggunakan spread, tetapi juga memungkinkan Anda untuk membuat objek subset dengan cara yang sama.
sumber
Meskipun sedikit lebih bertele-tele, Anda dapat mencapai apa yang orang lain rekomendasikan underscore / lodash selama 2 tahun yang lalu, dengan menggunakan Array.prototype.reduce .
Pendekatan ini menyelesaikannya dari sisi lain: alih-alih mengambil objek dan meneruskan nama properti ke sana untuk mengekstrak, ambil array nama properti dan kurangi menjadi objek baru.
Sementara itu lebih verbose dalam kasus paling sederhana, panggilan balik di sini cukup berguna, karena Anda dapat dengan mudah memenuhi beberapa persyaratan umum, misalnya mengubah properti 'warna' menjadi 'warna' pada objek baru, susun array, dll. - semua hal-hal yang perlu Anda lakukan ketika menerima objek dari satu layanan / perpustakaan dan membangun objek baru yang diperlukan di tempat lain. Walaupun garis bawah / lodash adalah lib yang sangat baik dan diimplementasikan dengan baik, ini adalah pendekatan yang saya pilih untuk mengurangi ketergantungan pada vendor, dan pendekatan yang lebih sederhana, lebih konsisten ketika logika membangun-subset saya menjadi lebih kompleks.
edit: versi es7 yang sama:
sunting: Contoh yang bagus untuk kari, juga! Minta fungsi 'pilih' mengembalikan fungsi lainnya.
Di atas cukup dekat dengan metode lain, kecuali itu memungkinkan Anda membangun 'pemilih' dengan cepat. misalnya
Apa yang sangat rapi tentang pendekatan ini, adalah Anda dapat dengan mudah memasukkan 'picks' yang dipilih ke dalam apa pun yang berfungsi, misalnya
Array#map
:sumber
function showToy({ color, height }) {
hanya akan menempatkan apa yang Anda butuhkan dalam ruang lingkup. Thereduce
Pendekatan terutama masuk akal ketika Anda menyederhanakan objek untuk serialisasi.const pick = (obj, props) => props.reduce((a, e) => (a[e] = obj[e], a), {});
fetch
), jadi saya akan merekomendasikan menambahkan komentar yang menjelaskan penggunaan operator koma.Destrukturisasi ES6
Sintaksis restrukturisasi memungkinkan untuk merusak dan menggabungkan kembali suatu objek, dengan parameter fungsi atau variabel.
Batasannya adalah bahwa daftar kunci sudah ditentukan sebelumnya, mereka tidak dapat didaftar sebagai string, seperti yang disebutkan dalam pertanyaan. Destrukturisasi menjadi lebih rumit jika kuncinya adalah non-alfanumerik, misalnya
foo_bar
.The downside adalah bahwa ini mengharuskan untuk menduplikasi daftar kunci, ini menghasilkan kode verbose jika daftar panjang. Karena merusak duplikat sintaksis objek objek dalam kasus ini, daftar dapat disalin dan ditempel sebagaimana adanya.
Keuntungannya adalah bahwa itu adalah solusi yang alami untuk ES6.
IIFE
Variabel sementara
Daftar string
Daftar sewenang-wenang dari kunci yang dipilih terdiri dari string, sesuai dengan pertanyaan. Ini memungkinkan untuk tidak menentukan sebelumnya dan menggunakan variabel yang berisi nama-nama kunci, seperti
pick(obj, 'foo', someKey, ...moreKeys)
.Satu kalimat menjadi lebih pendek pada setiap edisi JS.
ES5
ES6
Atau dengan operator koma:
ES2019
ECMAScript 2017 memiliki
Object.entries
danArray.prototype.includes
, ECMAScript 2019 memilikiObject.fromEntries
, mereka dapat di-polyfilled ketika dibutuhkan dan membuat tugas lebih mudah:Satu kalimat
pick
dapat ditulis ulang sebagai fungsi pembantu yang mirip dengan Lodash atau diomit
mana daftar kunci dilewatkan melalui argumen:Catatan tentang kunci yang hilang
Perbedaan utama antara perusakan dan fungsi konvensional seperti Lodash
pick
adalah bahwa perusakan mencakup kunci pilihan yang tidak ada denganundefined
nilai dalam subset:Perilaku ini mungkin diinginkan atau tidak. Itu tidak dapat diubah untuk merusak sintaksis.
Sementara
pick
dapat diubah untuk memasukkan kunci yang hilang dengan mengulangi daftar kunci yang dipilih sebagai gantinya:sumber
obj
variabel adalah variabel yang menyimpan objek. Jika nama variabel Anda berbeda, gunakan sajaobj
.Object.keys(obj)
. Ngantuk.Tidak ada yang seperti itu built-in ke perpustakaan inti, tetapi Anda dapat menggunakan perusakan objek untuk melakukannya ...
Anda juga bisa menulis fungsi utilitas melakukannya ...
Perpustakaan seperti Lodash juga punya
_.pick()
.sumber
Saya menambahkan jawaban ini karena tidak ada jawaban yang digunakan
Comma operator
.Ini sangat mudah dengan
destructuring assignment
dan,
OperatorDengan penyempurnaan tertentu untuk penetapan properti dinamis, itu bisa terlihat seperti ini:
sumber
'use strict'
). Saya mendapatkanReferenceError: a is not defined
.a
danc
- berhati-hatilah untuk tidak secara acak menimpa vars lokal atau global tergantung pada konteksnya. (Jawaban yang diterima menghindari masalah ini dengan menggunakan dua variabel lokal dalam fungsi inline, yang jatuh keluar dari ruang lingkup setelah eksekusi segera.)Satu lagi solusi:
Ini terlihat jauh lebih mudah dibaca daripada jawaban apa pun sejauh ini, tapi mungkin itu hanya aku!
sumber
subset = {color: elmo.color, height: elmo.color}
, saya akan memiliki setidaknya ... well, mungkin sepeser pun.Anda dapat menggunakan Lodash juga.
Melengkapi, katakanlah Anda memiliki array "elmo" s:
Jika Anda menginginkan perilaku yang sama, menggunakan lodash, Anda cukup:
sumber
Destrukturisasi menjadi variabel yang dinamai secara dinamis adalah mustahil di JavaScript seperti yang dibahas dalam pertanyaan ini .
Untuk mengatur kunci secara dinamis , Anda dapat menggunakan fungsi pengurangan tanpa memutasi objek sebagai berikut:
di bawah ini adalah versi menggunakan pengurangan dengan klon tunggal (memperbarui nilai awal yang diteruskan untuk mengurangi)
sumber
Solusi TypeScript:
Informasi pengetikan bahkan memungkinkan untuk penyelesaian otomatis:
Penghargaan untuk DefinitelyTyped untuk
U extends keyof T
trik!sumber
Gunakan
pick
metode perpustakaan lodash jika Anda sudah menggunakan.https://lodash.com/docs/4.17.10#pick
sumber
Solusi dinamis
Tampilkan cuplikan kode
sumber
Dengan cara lain ...
Anda dapat menggunakan fungsi ini dengan array Objects =)
sumber
Bagaimana tentang:
sumber
false
(atau palsu). jsfiddle.net/nfAs8keys[i] in obj
.Ini berfungsi untuk saya di konsol Chrome. Ada masalah dengan ini?
sumber
Merusak penugasan dengan properti dinamis
Solusi ini tidak hanya berlaku untuk contoh spesifik Anda tetapi lebih umum berlaku:
Anda dapat dengan mudah menentukan
subset4
dll. Untuk mempertimbangkan lebih banyak properti.sumber
Baik-tua
Array.prototype.reduce
:jawaban ini menggunakan operator koma ajaib, juga: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator
jika Anda ingin benar-benar mewah, ini lebih ringkas:
Menyatukan semuanya menjadi fungsi yang dapat digunakan kembali:
sumber
konversi argumen menjadi array
gunakan
Array.forEach()
untuk memilih propertisumber
sumber
Mencoba
sumber
Menambahkan 2 sen saya ke jawaban Ivan Nosov :
Dalam kasus saya, saya perlu banyak tombol untuk 'diiris' dari objek sehingga menjadi sangat cepat dan bukan solusi yang sangat dinamis:
Jadi di sini adalah solusi dinamis menggunakan eval:
sumber
Anda dapat memperluas jquery jika Anda inginkan di sini adalah kode sampel untuk satu slice:
ini biola untuk hal yang sama: http://jsfiddle.net/w633z/
sumber