Saya memiliki hash yang terlihat seperti ini:
params = { :irrelevant => "A String",
:choice1 => "Oh look, another one",
:choice2 => "Even more strings",
:choice3 => "But wait",
:irrelevant2 => "The last string" }
Dan saya ingin cara sederhana untuk menolak semua kunci yang bukan pilihan + int. Itu bisa berupa choice1, atau choice1 hingga choice10. Bervariasi.
Bagaimana cara memilih kunci hanya dengan pilihan kata dan digit atau digit setelahnya?
Bonus:
Ubah hash menjadi string dengan tab (\ t) sebagai pembatas. Saya melakukan ini, tetapi butuh beberapa baris kode. Biasanya master Rubician dapat melakukannya dalam satu atau lebih baris.
Jawaban:
Edit ke jawaban asli : Meskipun ini adalah jawaban (pada saat komentar ini) adalah jawaban yang dipilih, versi asli dari jawaban ini sudah usang.
Saya menambahkan pembaruan di sini untuk membantu orang lain menghindari teralihkan oleh jawaban ini seperti yang saya lakukan.
Seperti jawaban lain yang disebutkan, Ruby> = 2.5 menambahkan
Hash#slice
metode yang sebelumnya hanya tersedia di Rails.Contoh:
Akhir pengeditan. Berikut ini adalah jawaban asli yang saya kira akan berguna jika Anda menggunakan Ruby <2,5 tanpa Rails, meskipun saya membayangkan kasus ini sangat jarang pada saat ini.
Jika Anda menggunakan Ruby, Anda dapat menggunakan
select
metode ini. Anda harus mengonversi kunci dari Simbol ke String untuk melakukan kecocokan regexp. Ini akan memberi Anda Hash baru dengan hanya pilihan di dalamnya.atau Anda dapat menggunakan
delete_if
dan memodifikasi Hash misalnyaatau jika itu hanya kunci dan bukan nilai yang Anda inginkan maka Anda dapat melakukannya:
dan ini akan memberikan hanya Array kunci misalnya
[:choice1, :choice2, :choice3]
sumber
.select
adalah.reject
, jika itu membuat kode Anda lebih idiomatis.#slice
cara bekerja untuk saya pada 2.5.3 bahkan tanpa ActiveSupport.Di Ruby, pilih Hash # adalah opsi yang tepat. Jika Anda bekerja dengan Rails, Anda dapat menggunakan Hash # slice dan Hash # slice !. mis. (rel 3.2.13)
sumber
Cara termudah adalah memasukkan
gem 'activesupport'
(ataugem 'active_support'
).Kemudian, di kelas Anda, Anda hanya perlu melakukannya
dan untuk menelepon
Saya percaya itu tidak layak untuk mendeklarasikan fungsi lain yang mungkin memiliki bug, dan lebih baik menggunakan metode yang telah di-tweak selama beberapa tahun terakhir.
sumber
Cara termudah adalah memasukkan gem 'activesupport' (atau gem 'active_support').
params.slice(:choice1, :choice2, :choice3)
sumber
Jika Anda bekerja dengan rel dan memiliki kunci di daftar terpisah, Anda dapat menggunakan
*
notasi:Seperti jawaban lain yang dinyatakan, Anda juga dapat menggunakan
slice!
untuk memodifikasi hash di tempat (dan mengembalikan kunci / nilai yang terhapus).sumber
Ini adalah satu baris untuk menyelesaikan pertanyaan asli lengkap:
Tetapi sebagian besar solusi di atas adalah memecahkan kasus di mana Anda perlu mengetahui kunci sebelumnya, menggunakan
slice
atau regexp sederhana.Berikut adalah pendekatan lain yang berfungsi untuk kasus penggunaan yang sederhana dan lebih kompleks, yang dapat ditukar saat runtime
Sekarang tidak hanya ini memungkinkan untuk logika yang lebih kompleks pada pencocokan kunci atau nilai, tetapi juga lebih mudah untuk menguji, dan Anda dapat menukar logika pencocokan saat runtime.
Mantan untuk memecahkan masalah asli:
sumber
Dengan
Hash::select
:sumber
Jika Anda ingin hash yang tersisa:
atau jika Anda hanya ingin kunci:
sumber
Masukkan ini ke inisialisasi
Maka Anda bisa melakukannya
atau
sumber
sumber
Adapun pertanyaan bonus:
Jika Anda memiliki output dari
#select
metode seperti ini (daftar array 2-elemen):maka cukup ambil hasil ini dan jalankan:
Jika Anda memiliki keluaran dari
#delete_if
metode seperti ini (hash):kemudian:
sumber
map
Diblokir karena itu argumen. Anda dapat membuat blok dengan cepat, dengan&:method
konstruksi, yang akan membuat blok{|v| v.method }
. Dalam kasus saya&:last
disebut argumen array (array 2-elemen). Jika Anda ingin bermain dengannya, pertama-tama periksa argumen apa yang Anda terima ke dalam blok (dapatkan 1 argumen, jangan dekonstruksi menjadi beberapa argumen!) Dan cobalah untuk menemukan 1 metode (Anda tidak dapat mengaitkan metode dengan&:method
) yang akan mengembalikan apa yang Anda inginkan. ingin. Jika memungkinkan, maka Anda dapat menggunakan pintasan, jika tidak, maka Anda perlu blok penuhsumber
Saya punya masalah yang sama, dalam kasus saya solusinya adalah liner satu yang bekerja bahkan jika kunci bukan simbol, tetapi Anda harus memiliki kunci kriteria dalam array
Contoh lain
sumber