私はPerlの人で、しばらくの間このようなハッシュを作成しました。
my%date; #スカラーが以前に「my」で呼び出されたと仮定します $ date {$ month} {$ day} {$ hours} {$ min} {$ sec} ++
今私はRubyを学んでいますが、これまでのところ、このツリーを使用することが多くのキーと値を実行する方法であることがわかりました。Perlで使用する単純な形式を使用する方法はありますか。一行?
@ date = { 月=> { 日=> { 時間=> { 分=> { 秒=> 1 } } } } }
残念ながら、簡単で実用的な方法はありませんがあります。 Ruby同等のものは、次のような醜い、醜い獣になります。
((((@date[month] ||= {})[day] ||= {})[hours] ||= {})[min] ||= {})[sec] = 1
ただし、ハッシュに欠落しているキーにデフォルト値を割り当てる方法があります。
@date = Hash.new { |hash, key| hash[key] = {} }
# @date[:month] is set to a new, empty hash because the key is missing.
@date[:month][:day] = 1
残念ながら、これは再帰的には機能しません。
...あなたがいない限り自分で作成してください; Rubyのためにやった!
class Hash
def self.recursive
new { |hash, key| hash[key] = recursive }
end
end
@date = Hash.recursive
@date[month][day][hours][min][sec] = 1
# @date now equals {month=>{day=>{hours=>{min=>{sec=>1}}}}}
ただし、未設定の値はすべてnil
ではなく{}
になっていることに注意してください。
->f{f[f]}[->f{Hash.new{|h,k|h[k]=f[f]}}]
明らかに。
@molfの回答に似ていますが、モンキーパッチがないオプションがいくつかあります。
ファクトリメソッドの使用:
def hash_tree
Hash.new do |hash, key|
hash[key] = hash_tree
end
end
@date = hash_tree
@date[month][day][hours][min][sec] = 1
カスタムクラスの場合:
class HashTree < Hash
def initialize
super do |hash, key|
hash[key] = HashTree.new
end
end
end
@date = HashTree.new
@date[month][day][hours][min][sec] = 1
上記のラムダ式と比較すると、これはより単純で、1行でもあります。
Hash.new {|h,k| h[k] = Hash.new(&h.default_proc) }
記号の使用はうまくいったようです:
ree-1.8.7-2009.10 > @date = {:month =>{:day => {:hours => {:min => {:sec => 1 } } } } }
=> {:month=>{:day=>{:hours=>{:min=>{:sec=>1}}}}}
次に、次のようにvalを取得できます。
ree-1.8.7-2009.10 > @date[:month][:day]
=> {:hours=>{:min=>{:sec=>1}}}
Rubyは最初から自動生存を行うことができますが、その機能を簡単に追加できるようには見えません。Googleで「Ruby自動生存」を検索すると次のようになります。
http://t-a-w.blogspot.com/2006/07/autovivification-in-Ruby.html
これには、探している方法で機能するハッシュを作成する方法の適切な例が含まれています。
Rubyハッシュの自動生存(ファセット) も役立つ場合があります。
Facets gemのHash.autonew
を使用して、Molfの回答に示されているrecursive
関数と同じことを行うことができます。
require 'xkeys'
date = {}.extend XKeys::Hash
date[month, day, hours, min, sec, :else => 0] += 1