2010-07-26 30 views
23

我是一個Perl的人,我做了哈希像這一段時間:Ruby中的單線程嵌套哈希創建? (我來自Perl的)

 
my %date; 

#Assume the scalars are called with 'my' earlier 

$date{$month}{$day}{$hours}{$min}{$sec}++ 

現在我學習Ruby和我迄今發現,使用這種樹是必經之路做許多鑰匙和價值。有什麼方法可以使用我使用Perl的簡單格式使用一行?

 
@date = {                                          
     month => {                                         
      day => {                                         
      hours => {                                        
       min => {                                        
       sec => 1                                       
       }                                          
      }                                          
      }                                           
     }                                                                                      
     }     
+0

我不知道怎樣做到這一點的開箱。你可以用一個方法來擴展Array或Hash類,方法就像'[month,day,hours,min,sec,1]'作爲一個參數,並將它轉換爲那種哈希值,如果這是你的東西認爲是有用的。 – Karl 2010-07-26 21:22:19

+0

在我看來,Ruby人使用不同的方式在正在運行的腳本中存儲信息。我在perl中使用像瘋狂一樣的哈希來保持我的數據獨特和分類。在這種情況下是否有更好的方法來存儲數據? 我在日誌分析腳本中使用此代碼段,並且可能會爲需要監視和保持分類的不同日誌條目添加更多密鑰。 – BioDevMike 2010-07-26 21:35:26

+1

其他「哈希在紅寶石自動生成」問題:http://stackoverflow.com/questions/170223/hashes-of-hashes-idiom-in-ruby http://stackoverflow.com/questions/3148747/is-auto-initialization多維散列數組 - 可能在ruby中,它是和http://stackoverflow.com/questions/3172342/how-to-handle-combination-for-auto-vivifying-hash -in-ruby – 2010-07-26 21:57:27

回答

41

不幸的是,有沒有簡單,實用的方式。一個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

+0

感謝您的一個很好的答案。還有一件事。你將如何去存儲解析的數據?我在perl中使用散列函數,你在存儲分類的分析數據方面做了什麼? (我對我的問題帖子的其他評論有更多) – BioDevMike 2010-07-26 21:43:37

+0

如果您需要月份,月份+日期,月份+日期+小時等數據,那麼您的方法是可以的。如果您需要使用其他方法,那麼這取決於您的使用情況。你甚至可以使用'[month,day,hours,min,sec]'這樣的數組或者一個簡單的字符串作爲散列鍵。但我不能不知道更多。 – molf 2010-07-26 21:56:29

+0

我也發現我可以很容易地粘在符號中: @date [month.to_sym] [day.to_sym] [hours.to_sym] [min.to_sym] [sec.to_sym] = + 1 無論如何要堅持進入該遞歸函數來自動sym鍵? – BioDevMike 2010-07-28 17:32:56

1

使用符號似乎工作:

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}}} 
+3

不是一個有用的答案。 – friedo 2010-07-26 21:27:09

+0

真的嗎?見上面.... – nicholasklick 2010-07-26 21:31:59

+0

現在,你已經編輯它,我會刪除我的-1 :) – friedo 2010-07-26 21:51:10

1

它看起來並不像Ruby可以從一開始做自動激活,但您可以輕鬆添加該功能。一種「紅寶石自動激活」在谷歌搜索得到:

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

其中包含如何創建一個哈希,將工作你正在尋找的路上一個體面的例子。

ruby hash autovivification (facets)也可能有幫助。

+0

感謝您的這些鏈接。你獲得第二名。我學到了一個新詞「autovivification」。 – BioDevMike 2010-07-26 21:44:43

1

您可以使用Facets寶石的Hash.autonew做與Molf的答案中給出的recursive函數相同的功能。

13

這裏有幾個選項類似於@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 
16
->f{f[f]}[->f{Hash.new{|h,k|h[k]=f[f]}}] 

明顯。

+9

來自perl的人的理想選擇 – artemave 2013-07-11 10:17:20

+0

花了20分鐘才明白它。我將無法重現它。但它很酷。 – artemave 2013-07-11 10:49:22

+1

請添加解釋。 – artemave 2013-07-11 10:51:12

11

相比於上面給出的Lambda表達式,這是簡單,也是在一條線:

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