Apa cara (tercepat / terbersih / mudah) untuk mengubah semua kunci dalam hash dari string ke simbol di Ruby?
Ini akan berguna saat mengurai YAML.
my_hash = YAML.load_file('yml')
Saya ingin dapat menggunakan:
my_hash[:key]
Daripada:
my_hash['key']
hash.symbolize_keys
danhash.deep_symbolize_keys
lakukan pekerjaan jika Anda menggunakan Rails.Jawaban:
Di Ruby> = 2.5 ( docs ) Anda dapat menggunakan:
Menggunakan versi Ruby yang lebih lama? Berikut ini adalah satu-liner yang akan menyalin hash ke yang baru dengan tombol yang dilambangkan:
Dengan Rails Anda dapat menggunakan:
sumber
each_with_object
seperti:my_hash.each_with_object({}){|(k,v), h| h[k.to_sym] = v}
.tap
metode ini untuk menghapus kebutuhan untuk lulusmemo
di akhir. Saya telah membuat versi yang dibersihkan dari semua solusi (yang rekursif juga) gist.github.com/Integralist/9503099Berikut metode yang lebih baik, jika Anda menggunakan Rails:
params. symbolize_keys
Tamat.
Jika tidak, lepas saja kode mereka (itu juga ada di tautan):
sumber
symbolize_keys
dengan URL baru & yang berfungsi (Rails 3). Saya awalnya hanya memperbaiki URLto_options
, tetapi tidak ada dokumentasi di tautan itu.symbolize_keys
sebenarnya memiliki deskripsi, jadi saya menggunakannya sebagai gantinya.hash.stringify_keys
bekerjalah.Untuk kasus spesifik YAML di Ruby, jika kunci dimulai dengan '
:
', mereka akan secara otomatis diinternir sebagai simbol.Keluaran:
sumber
YAML#load_file
ke default semua kunci untuk simbol alih-alih string tanpa harus memulai setiap kunci dengan titik dua?Bahkan lebih singkat:
sumber
my_hash.map { |k, v| [k.to_sym, v] }.to_h
jika Anda menggunakan Rails, ini jauh lebih sederhana - Anda dapat menggunakan HashWithIndifferentAccess dan mengakses kunci baik sebagai String maupun sebagai Simbol:
Lihat juga:
http://api.rubyonrails.org/classes/ActiveSupport/HashWithIndifferentAccess.html
Atau Anda dapat menggunakan Permata "Aspek Ruby" yang mengagumkan, yang berisi banyak ekstensi untuk kelas-kelas Ruby Core dan Perpustakaan Standar.
lihat juga: http://rubyworks.github.io/rubyfaux/?doc=http://rubyworks.github.io/facets/docs/facets-2.9.3/core.json#api-class-Hash
sumber
Karena
Ruby 2.5.0
Anda dapat menggunakanHash#transform_keys
atauHash#transform_keys!
.sumber
stringify_keys
atausymbolize_keys
.http://api.rubyonrails.org/classes/Hash.html#method-i-symbolize_keys
sumber
Inilah cara untuk melambangkan objek secara mendalam
sumber
Saya sangat suka permata Mash .
Anda dapat melakukannya
mash['key']
, ataumash[:key]
, ataumash.key
sumber
Jika Anda menggunakan json, dan ingin menggunakannya sebagai hash, di Ruby inti Anda bisa melakukannya:
symbolize_names : Jika disetel ke true, mengembalikan simbol untuk nama (kunci) dalam objek JSON. Kalau tidak, string dikembalikan. String adalah default.
Doc: Json # parse symbolize_names
sumber
symbol_hash = JSON.parse(JSON.generate(YAML.safe_load(FILENAME)), symbolize_names: true)
adalah cara yang cukup KERING (tetapi tidak efisien) untuk dengan cepat mendapatkan hash dengan kunci bersarang sebagai simbol jika berasal dari file YAML.params.symbolize_keys
juga akan bekerja. Metode ini mengubah kunci hash menjadi simbol dan mengembalikan hash baru.sumber
Sebuah modifikasi pada jawaban @igorsales
sumber
Di Rails Anda dapat menggunakan:
Mengubah ke:
sumber
deep_symbolize_keys
ditambahkan dalam ekstensi Hash Rails ' , tetapi itu bukan bagian dari inti Ruby.Begitu banyak jawaban di sini, tetapi fungsi satu metode rel adalah
hash.symbolize_keys
sumber
Ini adalah liner satu saya untuk hash bersarang
sumber
Dalam hal alasan Anda perlu melakukan ini adalah karena data Anda awalnya berasal dari JSON, Anda bisa melewatkan parsing ini dengan hanya meneruskan
:symbolize_names
opsi setelah menelan JSON.Tidak diperlukan Rails dan berfungsi dengan Ruby> 1.9
sumber
Anda bisa malas, dan membungkusnya dalam
lambda
:Tapi ini hanya akan berfungsi untuk membaca dari hash - bukan menulis.
Untuk melakukan itu, Anda bisa menggunakan
Hash#merge
Blok init akan mengonversi kunci satu kali sesuai permintaan, meskipun jika Anda memperbarui nilai untuk versi string kunci setelah mengakses versi simbol, versi simbol tidak akan diperbarui.
Anda juga bisa memiliki blok init tidak memperbarui hash, yang akan melindungi Anda dari kesalahan semacam itu, tetapi Anda masih rentan terhadap yang sebaliknya - memperbarui versi simbol tidak akan memperbarui versi string:
Jadi hal yang harus diperhatikan adalah beralih di antara dua bentuk utama. Tetap dengan satu.
sumber
Apakah sesuatu seperti pekerjaan berikut?
Ini akan menyalin hash, tetapi Anda tidak akan peduli tentang itu sebagian besar waktu. Mungkin ada cara untuk melakukannya tanpa menyalin semua data.
sumber
fwiw satu-baris yang lebih pendek:
sumber
Bagaimana dengan ini:
sumber
Ini untuk orang yang menggunakan
mruby
dan tidak memilikisymbolize_keys
metode apa pun yang ditentukan:Metode:
String
RuntimeError
sumber
!
masuksymbolize_keys
. Jika tidak berfungsi dengan baik.Array yang ingin kita ubah.
strings = ["HTML", "CSS", "JavaScript", "Python", "Ruby"]
Jadikan variabel baru sebagai array kosong sehingga kita dapat ". Menekan" simbol-simbol di.
simbol = []
Di sinilah kita mendefinisikan metode dengan blok.
strings.each {| x | symbols.push (x.intern)}
Akhir kode
Jadi ini mungkin cara paling mudah untuk mengonversi string menjadi simbol dalam array Anda di Ruby. Buat array string lalu buat variabel baru dan atur variabel ke array kosong. Kemudian pilih setiap elemen dalam larik pertama yang Anda buat dengan metode ".each". Kemudian gunakan kode blok untuk ".push" semua elemen dalam array baru Anda dan gunakan ".intern or .to_sym" untuk mengonversi semua elemen menjadi simbol.
Simbol lebih cepat karena menyimpan lebih banyak memori dalam kode Anda dan Anda hanya dapat menggunakannya sekali. Simbol yang paling umum digunakan untuk kunci dalam hash yang bagus. Saya bukan programmer ruby terbaik tetapi bentuk kode ini banyak membantu saya. Jika ada yang tahu cara yang lebih baik silakan berbagi dan Anda dapat menggunakan metode ini untuk hash juga!
sumber
Jika Anda ingin solusi vanila ruby dan karena saya tidak memiliki akses ke
ActiveSupport
sini adalah solusi melambangkan yang dalam (sangat mirip dengan yang sebelumnya)sumber
Dimulai pada Psych 3.0 Anda dapat menambahkan symbolize_names: option
Psych.load("---\n foo: bar") # => {"foo"=>"bar"}
Psych.load("---\n foo: bar", symbolize_names: true) # => {:foo=>"bar"}
Catatan: jika Anda memiliki versi Psych lebih rendah dari 3.0
symbolize_names:
akan diabaikan secara diam-diam.Ubuntu 18.04 saya memasukkannya di luar kotak dengan ruby 2.5.1p57
sumber
sumber
a
dengan tanda kurung untuk menguraikan argumen blok agar ini menjadi lebih singkat. Lihat jawaban saya misalnya.Ini bukan persis satu-liner, tetapi mengubah semua kunci string menjadi simbol, juga yang bersarang:
sumber
Saya suka one-liner ini, ketika saya tidak menggunakan Rails, karena saya tidak perlu membuat hash kedua dan menyimpan dua set data saat saya sedang memprosesnya:
Hash # delete mengembalikan nilai kunci yang dihapus
sumber
Facet 'Hash # deep_rekey juga merupakan pilihan yang baik, terutama:
Sampel:
sumber
Dalam ruby saya menemukan ini sebagai cara yang paling sederhana dan mudah dipahami untuk mengubah kunci string dalam hash menjadi simbol:
Untuk setiap kunci dalam hash, kita memanggil delete di atasnya yang menghilangkannya dari hash (juga menghapus mengembalikan nilai yang terkait dengan kunci yang telah dihapus) dan kami segera mengatur ini sama dengan kunci yang dilambangkan.
sumber
Mirip dengan solusi sebelumnya tetapi ditulis agak berbeda.
Kode tidak mengubah hash yang dimasukkan.
sumber