2014-10-27 51 views
0

我有一个Ruby的数组,看起来是这样的:将Ruby数组简化为唯一值计数的简洁方法?

animals = %w(dog cat bird cat dog bird bird cat) 

我需要让每一个独特的物品的计数值在数组中。我可以这样做:

dogs = 0 
cats = 0 
birds = 0 

animals.each do |animal| 
    dogs += 1 if animal == 'dog' 
    cats += 1 if animal == 'cat' 
    birds += 1 if animal == 'bird' 
end 

...但这种方法太冗长了。在Ruby中计算这些唯一计数的最简洁的方法是什么?

+0

检查这里的答案做的另一种方式http://stackoverflow.com/questions/5470725/how-to-group-by-count-in-array-不使用循环 – Alireza 2014-10-27 19:04:28

回答

5

我想你要找的是什么count

animals = %w(dog cat bird cat dog bird bird cat) 
dogs = animals.count('dog') #=> 2 
cats = animals.count('cat') #=> 3 
birds = animals.count('bird') #=> 3 
+0

哦,有趣!我不知道伯爵接受了一个论点! – Andrew 2014-10-27 19:00:36

+0

+1,我不知道那 – dax 2014-10-27 19:09:28

0

要做到这一点是将计数存储在一个哈希像这样最简单的方法:

animals = %w(dog cat bird cat dog bird bird cat) 
animal_counts = {} 
animals.each do |animal| 
    if animal_counts[animal] 
    animal_counts[animal] += 1 
    else 
    animal_counts[animal] = 1 
    end 
end 

每个门店这数组中的唯一项作为一个关键字,并作为值计算。它改进了你的代码,因为它不需要预先知道数组的内容。

+0

嗯,这对我来说似乎是一种矫枉过正。你说你不需要事先知道阵列的内容,我同意,这是正确的。但是,如果你没有把它们作为你新创建的哈希中的关键字,你将如何访问'dog','cat'或'bird'的数量? – Surya 2014-10-27 19:05:29

+0

您可以将其简化为:'animals.each_with_object({}){| a,c | c [a] =(c [a] || = 0)+1} => {“dog”=> 2,“cat”=> 3,“bird”=> 3}'。 – 2014-10-27 20:28:41

1
animals.uniq.map { |a| puts a, animals.count(a)} 
1

使用group_by

animals = %w(dog cat bird cat dog bird bird cat) 
hash = animals.group_by {|i| i} 
hash.update(hash) {|_, v| v.count} 

#=> hash = {"dog"=>2, "cat"=>3, "bird"=>3} 
+0

你的最后一行非常酷。我熟悉'update'的形式需要一个块,但我没有看到它有自己的散列“merge!”d。你可以考虑把块变量写成'| _,v,_ |'。 – 2014-10-27 20:46:23

相关问题