Untuk menambahkan pasangan baru ke Hash saya lakukan:
{:a => 1, :b => 2}.merge!({:c => 3}) #=> {:a => 1, :b => 2, :c => 3}
Apakah ada cara serupa untuk menghapus kunci dari Hash?
Ini bekerja:
{:a => 1, :b => 2}.reject! { |k| k == :a } #=> {:b => 2}
tapi saya berharap memiliki sesuatu seperti:
{:a => 1, :b => 2}.delete!(:a) #=> {:b => 2}
Penting bahwa nilai yang dikembalikan akan menjadi hash yang tersisa, jadi saya bisa melakukan hal-hal seperti:
foo(my_hash.reject! { |k| k == my_key })
dalam satu baris.
ruby-on-rails
ruby
ruby-on-rails-3
hashmap
ruby-hash
Misha Moroshko
sumber
sumber
Jawaban:
Rails memiliki tanda kecuali / kecuali! metode yang mengembalikan hash dengan kunci-kunci itu dihapus. Jika Anda sudah menggunakan Rails, tidak ada gunanya membuat versi Anda sendiri tentang ini.
sumber
require "active_support/core_ext/hash/except"
Oneliner ruby biasa, hanya berfungsi dengan ruby> 1.9.x:
Metode ketuk selalu mengembalikan objek yang dipanggil ...
Kalau tidak, jika Anda diharuskan
active_support/core_ext/hash
(yang secara otomatis diperlukan di setiap aplikasi Rails), Anda dapat menggunakan salah satu metode berikut tergantung pada kebutuhan Anda:kecuali menggunakan pendekatan daftar hitam, sehingga menghapus semua kunci yang terdaftar sebagai args, sedangkan slice menggunakan pendekatan daftar putih, sehingga menghapus semua kunci yang tidak terdaftar sebagai argumen. Ada juga versi bang dari metode tersebut (
except!
danslice!
) yang memodifikasi hash yang diberikan tetapi nilai kembalinya berbeda keduanya mengembalikan hash. Ini mewakili kunci yang dihapus untukslice!
dan kunci yang disimpan untukexcept!
:sumber
h
.Hash#except
tidak akan mengubah hash asli.h.dup.tap { |hs| hs.delete(:a) }
untuk menghindari memodifikasi hash asli.Mengapa tidak menggunakan saja:
sumber
merge
,merge!
,delete
, tapi tidak adadetele!
...foo(hash.delete(key) || hash)
delete
tidak tidak mengubah parameter dan jikadelete!
ada dan melakukan memodifikasi parameter-nya.Ada banyak cara untuk menghapus kunci dari hash dan mendapatkan hash yang tersisa di Ruby.
.slice
=> Ini akan mengembalikan kunci yang dipilih dan tidak menghapusnya dari hash asli. Gunakanslice!
jika Anda ingin menghapus kunci secara permanen menggunakan yang lainslice
..delete
=> Ini akan menghapus kunci yang dipilih dari hash asli (hanya dapat menerima satu kunci dan tidak lebih dari satu)..except
=> Ini akan mengembalikan kunci yang tersisa tetapi tidak menghapus apa pun dari hash asli. Gunakanexcept!
jika Anda ingin menghapus kunci secara permanen menggunakan yang lainexcept
..delete_if
=> Jika Anda perlu menghapus kunci berdasarkan nilai. Ini jelas akan menghapus kunci yang cocok dari hash asli..compact
=> Digunakan untuk menghapus semuanil
nilai dari hash. Gunakancompact!
jika Anda ingin menghapusnil
nilai - nilai secara permanen menggunakan yang laincompact
.Hasil berdasarkan Ruby 2.2.2.
sumber
slice
danexcept
ditambahkan dengan menggunakanActiveSupport::CoreExtensions::Hash
. Mereka bukan bagian dari inti Ruby. Mereka dapat digunakan olehrequire 'active_support/core_ext/hash'
Hash#slice
ada di perpustakaan standar. ruby-doc.org/core-2.5.0/Hash.html#method-i-slice Yay!Jika Anda ingin menggunakan Ruby murni (tanpa Rails), tidak ingin membuat metode ekstensi (mungkin Anda membutuhkan ini hanya di satu atau dua tempat dan tidak ingin mencemari namespace dengan banyak metode) dan tidak ingin sunting hash di tempat (yaitu, Anda penggemar pemrograman fungsional seperti saya), Anda dapat 'memilih':
sumber
Saya sudah mengatur ini sehingga .remove mengembalikan salinan hash dengan kunci dihapus, sambil menghapus! memodifikasi hash itu sendiri. Ini sesuai dengan konvensi batu delima. misal, dari konsol
sumber
Anda dapat menggunakan
except!
darifacets
permata:Hash asli tidak berubah.
EDIT: seperti yang dikatakan Russel, aspek memiliki beberapa masalah tersembunyi dan tidak sepenuhnya kompatibel dengan API dengan ActiveSupport. Di sisi lain ActiveSupport tidak selengkap segi. Pada akhirnya, saya akan menggunakan AS dan membiarkan kasus tepi dalam kode Anda.
sumber
require 'facets/hash/except'
dan tidak ada "masalah" (tidak yakin masalah apa yang akan terjadi, selain yang tidak 100% AS API). Jika Anda melakukan proyek Rails menggunakan AS masuk akal, jika tidak Facet memiliki jejak yang jauh lebih kecil.Alih-alih menambal monyet atau termasuk perpustakaan besar yang tidak perlu, Anda dapat menggunakan penyempurnaan jika Anda menggunakan Ruby 2 :
Anda dapat menggunakan fitur ini tanpa mempengaruhi bagian lain dari program Anda, atau harus menyertakan perpustakaan eksternal yang besar.
sumber
dalam Ruby murni:
sumber
Lihat Ruby on Rails: Hapus beberapa kunci hash
sumber
each
akan mengembalikan array.Sangat bagus jika delete mengembalikan pasangan delete dari hash. Saya sedang melakukan ini:
sumber
Ini adalah cara satu baris untuk melakukannya, tetapi tidak terlalu mudah dibaca. Sebaiknya gunakan dua baris.
sumber
Hash#except
danHash#except!
sudah cukup disebutkan. TheProc.new
Versi ini tidak sangat mudah dibaca seperti yang Anda sebutkan dan juga lebih rumit daripadause_remaining_hash_for_something(begin hash.delete(:key); hash end)
. Mungkin hapus saja jawaban ini.Berbagai cara untuk menghapus Key di Hash. Anda dapat menggunakan Metode apa pun dari bawah
Begitu banyak cara di sana, Anda dapat melihat Ruby doc of Hash di sini .
Terima kasih
sumber
Ini juga akan berfungsi:
hash[hey] = nil
sumber