如何在哈希数组中计算值

4

我有一个哈希数组

[ {:name => "bob", :type => "some", :product => "apples"},
  {:name => "ted", :type => "other", :product => "apples"},.... 
  {:name => "Will", :type => "none", :product => "oranges"} ]

我想知道是否有一种简单的方法来计算产品数量并将计数以及值存储在数组或哈希表中,内容如下:

我希望结果类似于:

@products =  [{"apples" => 2, "oranges => 1", ...}]

根据您的需求,我不认为有必要将哈希保留在数组内部。如果有任何原因,请告诉我们。 - Arup Rakshit
您期望的结果无效。无法获得该结果。 - sawa
5个回答

9
你可以按照以下方式操作:
array = [
  {:name => "bob", :type => "some", :product => "apples"},
  {:name => "ted", :type => "other", :product => "apples"},
  {:name => "Will", :type => "none", :product => "oranges"} 
]

array.each_with_object(Hash.new(0)) { |h1, h2| h2[h1[:product]] += 1 }
# => {"apples"=>2, "oranges"=>1}

谢谢你的帮助。我知道在 Ruby 中有一种简单的方法来做到这一点。我尝试使用 inject,但没有成功。谢谢 :) - user2980830
1
对于注入(inject),请尝试使用array.inject(Hash.new(0)) { |hash, item| hash[item[:product]] += 1; hash } - jvnill
@user2980830 请阅读 jvnil 的评论。 - Arup Rakshit
谢谢,使用inject和each_with_object有什么优势吗?我看它们会产生相同的结果。 - user2980830
这里有@sawa的一个很好的解释:https://dev59.com/dm035IYBdhLWcg3wVuh1#5481396 - jvnill

2

虽然不完全符合原帖的要求,但这对许多人可能有所帮助。如果你只是想查看特定产品的数量,可以这样做:

array = [
  {:name => "bob", :type => "some", :product => "apples"},
  {:name => "ted", :type => "other", :product => "apples"},
  {:name => "Will", :type => "none", :product => "oranges"} 
]

array.count { |h| h[:product] == 'apples' }
# => 2

2

0
你可以数一下:
hashes = [
  {:name => "bob", :type => "some", :product => "apples"},
  {:name => "ted", :type => "other", :product => "apples"},
  {:name => "Will", :type => "none", :product => "oranges"}
]

hashes.inject(Hash.new(0)) { |h,o| h[o[:product]] += 1; h }

或者也许...

hashes.instance_eval { Hash[keys.map { |k| [k,count(k)] }] }

我不知道哪个更高效,但后者读起来有点奇怪。


你能试试在IRB中运行你给出的代码吗?hashes.inject(Hash.new(0)) { |h,(_,value)| h[value] += 1 }。它完全错了。 - Arup Rakshit
我之前尝试使用过inject来计算项目数量,但从未见过"(_,value)"这样的用法,感谢您的回复。 - user2980830

0

我会这样做:

items =[ {:name => "bob", :type => "some", :product => "apples"},
  {:name => "ted", :type => "other", :product => "apples"},
  {:name => "Will", :type => "none", :product => "oranges"} ]

 counts = items.group_by{|x|x[:product]}.map{|x,y|[x,y.count]}
 p counts #=> [["apples", 2], ["oranges", 1]]

如果你需要将它作为哈希表,只需执行以下操作:

 Hash[counts]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接