2016-02-12 88 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]]