2016-02-12 127 views
1

我試圖創建將採取散列的方法:轉換哈希到一個數組

{"H"=> 1, "e"=> 1, "l"=> 3, "o"=> 2, "W"=> 1, "r"=> 1, "d"=> 1} 

作爲參數,並返回其鍵值對的數組像這樣:

arr = [["H", 1], ["e", 1], ..., ["d", 1]] 

我有以下,但它是有缺陷的:

def toCountsArray(counts) 
    arr = [] 
    i = 0 
    counts.each do |key, value| 
    arr[i].push [key, value] 
    i += 1 
    end 
    return arr 
end 

我不應該使用to_a方法或任何形式的這樣的幫手。任何幫助或指導表示讚賞。

+2

注意,編寫Ruby的時候,有一個非常強的約定方法名是'underscore_style',不'mixedCase'。這是一件小事,但它可以幫助你的代碼更好地適應,避免重音編程。 – tadman

+0

我遵循教授向我們提供的編碼風格,但我同意你的意見。 @tadman –

+0

我會問你的教授一個風格指南的鏈接,解釋這些古怪的約定,因爲我從來沒有見過一個倡導者。如果他們有一些不規則的要求,我希望他們在某個地方編碼。 – tadman

回答

3

你基本上沒有。對to_a的任意限制很奇怪,因爲有很多方法可以有效地實現相同的目的。不過,解決您最初的例子:

array = [ ] 
counts.each do |pair| 
    array << pair 
end 

這是做to_a的混亂的方式,但它應該工作。你的錯誤是試圖附加到的特定元素array,而不是附加到數組本身。

做這種操作時要使用的模式是這樣的:

counts = Hash.new(0) 

,隨着0每個元素的默認值創建一個散列。這樣可以避免爲了分配未定義的鍵而必須進行的跳舞。

還有一些其他的事情可以做,以減少這一點,並使其更紅寶石般:

def count_chars(string) 
    string.chars.each_with_object(Hash.new(0)) do |char, counts| 
    case (char) 
    when ' ' 
     # Ignored 
    else 
     counts[char] += 1 
    end 
    end 
end 

each_with_object方法,它遍歷得心應手一個數組經過一個對象,而每次迭代可以利用。結合使用哈希與默認值的技巧使得這個相當整齊。

如果您有更長的「忽略」字符列表,請將其表示爲數組。 string.chars - exclusions然後可以刪除不需要的。我在這裏使用了一個case聲明來使添加特殊行爲更容易。

+1

謝謝,有道理。我感謝您的幫助。 –

0

代替

arr[i].push [key, value] 

使用

arr.push [key, value] 

因爲arr[i]指的是第i個元素

0

我會做這樣的事情:

hash = { "H"=> 1, "e"=> 1, "l"=> 3, "o"=> 2, "W"=> 1, "r"=> 1, "d"=> 1 } 

hash.each_with_object([]) { |kv, a| a << kv } 
#=> [["H",1],["e",1],["l",3],["o",2],["W",1],["r",1],["d",1]] 
1
hash = { "H"=> 1, "e"=> 1, "l"=> 3, "o"=> 2, "W"=> 1, "r"=> 1, "d"=> 1 } 

p [*hash] 
# => [["H", 1], ["e", 1], ["l", 3], ["o", 2], ["W", 1], ["r", 1], ["d", 1]] 
0

你可以這樣做:

def to_counts_array(counts) 
    counts.map { |k, v| [k, v] } 
end 

h = { "H"=> 1, "e"=> 1, "l"=> 3, "o"=> 2, "W"=> 1, "r"=> 1, "d"=> 1 } 
to_counts_array(h) 

雖然我喜歡@ steenslag的回答也是如此。

0

另一種方法,只映射到自我:

x.map &:itself #=> [["H", 1], ["e", 1], ["l", 3], ["o", 2], ["W", 1], ["r", 1], ["d", 1]]