2014-10-08 36 views
0

創建方法時,發現一個數組的方式,我看到人們通過使用默認值0哈希迭代陣列上:找到一個陣列的模式在Ruby中

def mode(array) 
    hash = Hash.new(0) 
    array.each do |i| 
    hash[i]+=1 
    end 
end 

freq = arr.inject(Hash.new(0)) { |h,v| h[v] += 1; h } 

有人可以解釋塊的以下部分?

hash[i] = hash[i] + 1 or h[v] = h[v] + 1 

迭代器如何知道將+1添加到散列的每個唯一鍵?例如:

array = [1,1,1,2,3] 
freq = arr.inject(Hash.new(0)) { |h,v| h[v] += 1; h } 
#=> {1:3, 2:1, 3:1} 

如果有人可以解釋如何找到一個數組的模式,我將不勝感激。

+1

呃,代碼是儘可能清楚的,我不知道如何更好地解釋它。哈希值只爲每個值使用一個計數器,默認值爲'0',每次再次看到一個值時增加'1'。 – 2014-10-08 05:20:15

+0

'{1:3,2:1,3:1}'不是有效的Ruby對象。 – sawa 2014-10-08 06:07:26

回答

1

在第一個示例中,您需要該方法來返回所創建的散列,或者對散列進行一些處理以計算模式。讓我們來試試吧,剛返回哈希(所以我已經添加hash作爲最後一行):

def hash_for_mode(array) 
    hash = Hash.new(0) 
    array.each do |i| 
    hash[i]+=1 
    end 
    hash 
end 

array = [1,3,1,4,3] 
hash_for_mode(array) #=> {1=>2, 3=>2, 4=>1} 

隨着hash_for_mode你可以很容易地計算模式。

通過定義散列h = Hash.new(0),我們告訴Ruby默認值爲零。由此,我們的意思是,如果執行的計算取決於h[k],當k不是h的關鍵時,h[k]將被設置爲等於默認值。

例如,考慮將第一個值array(在本例中爲1)傳遞給塊並分配給塊變量ihash沒有鑰匙1。 (它還沒有鑰匙。)hash[1] += 1hash[1] = hash[1] + 1的簡寫,因此Ruby將在等號右側替換hash[1],默認值爲零,結果爲hash[1] => 1

array第三值(另一個1)傳遞到塊,hash[1]已經存在(並等於1),所以我們只需要添加一個給它一個新的價值2

如果你想知道,如果我們有:

hash = Hash.new(0) 
hash[1] += 1 
hash   #=> {1=>1} 
puts hash[2] #=> nil 
hash   #=> {1=>1} 

也就是說,僅僅是引用的一個關鍵,是不是在哈希(這裏puts hash[2]),一個鍵值對不添加到哈希。

另一種常見的方式做同樣的事情是:

def hash_for_mode(array) 
    array.each_with_object({}) { |i,hash| hash[i] = (hash[i] || 0) + 1 } 
end 

hash_for_mode(array) #=> {1=>2, 3=>2, 4=>1} 

這依賴於這樣一個事實:

(hash[i] || 0) #=> hash[i] if hash already has a key i 
(hash[i] || 0) #=> 0 if hash does not have a key i, so hash[k]=>nil 

(這需要你的哈希值不包含任何對​​。)

此外,請注意,而不是先聲明:

hash = {} 

最後聲明:

hash 

我用的方法Enumerable#each_with_object,它返回的哈希值。這裏優選使用Enumerable#inject(又名reduce),因爲您不需要將hash返回給迭代器(不需要; h)。

+0

「如果散列使用未包含在散列中的密鑰」k「執行計算,則將密鑰值對」k => 0「添加到散列」 - 不是真的,它只是在讀取操作中返回的默認值。 'h = Hash.new(0);把h [1];把h.inspect'顯示爲'0',然後是'{}'。它是OP代碼中'+ ='的賦值部分,在添加默認的'0'和文字'1'後創建鍵值對'1 => 1'。密鑰對「1 => 0」絕不在OP代碼中的哈希中。不過,其餘的+1。 – Amadan 2014-10-08 07:22:51

+0

謝謝阿馬丹。我會糾正這一點。 – 2014-10-08 07:59:31