web-dev-qa-db-ja.com

Rubyでのワンライナーネストハッシュ作成? (私はPerlから来ました)

私はPerlの人で、しばらくの間このようなハッシュを作成しました。

 my%date; 
 
#スカラーが以前に「my」で呼び出されたと仮定します
 
 $ date {$ month} {$ day} {$ hours} {$ min} {$ sec} ++ 

今私はRubyを学んでいますが、これまでのところ、このツリーを使用することが多くのキーと値を実行する方法であることがわかりました。Perlで使用する単純な形式を使用する方法はありますか。一行?

 @ date = {
月=> {
日=> {
時間=> {
分=> {
秒=> 1 
} 
} 
} 
} 
} 
28
BioDevMike

残念ながら、簡単で実用的な方法はありませんがあります。 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ではなく{}になっていることに注意してください。

48
molf
->f{f[f]}[->f{Hash.new{|h,k|h[k]=f[f]}}]

明らかに。

17
Xavier Shay

@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
17
opsb

上記のラムダ式と比較すると、これはより単純で、1行でもあります。

Hash.new {|h,k| h[k] = Hash.new(&h.default_proc) }
14
Horst

記号の使用はうまくいったようです:

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}}}
2
nicholasklick

Rubyは最初から自動生存を行うことができますが、その機能を簡単に追加できるようには見えません。Googleで「Ruby自動生存」を検索すると次のようになります。

http://t-a-w.blogspot.com/2006/07/autovivification-in-Ruby.html

これには、探している方法で機能するハッシュを作成する方法の適切な例が含まれています。

Rubyハッシュの自動生存(ファセット) も役立つ場合があります。

1
Eric Strom

Facets gemのHash.autonewを使用して、Molfの回答に示されているrecursive関数と同じことを行うことができます。

1
Ken Bloom
require 'xkeys'
date = {}.extend XKeys::Hash

date[month, day, hours, min, sec, :else => 0] += 1
0
Brian K