2013-10-12 35 views
0

我有一个数组:红宝石计数值的范围在阵列

[1,2,3,4,5,6,7,8,9,10] 

和我需要计数三个单独的东西。

1)所有值小于或等于6

2)所有值等于78。所有的值大于8

什么是最好的方式来做到这一点,而不计算单个值并将它们加在一起?

+0

你的意思是_add_,或_count frequency_? – zeantsoi

+0

循环一次数组。并做所有的操作。 – AshwinKumarS

回答

1
arr = [1,2,3,4,5,6,7,8,9,10] 

arr.select {|e| e <= 6}.size 
#=> 6 

arr.select {|e| e == 7 || e == 8}.size 
#=> 2 

arr.select {|e| e > 8}.size 
#=> 2 
+0

这似乎是找到我需要的最清洁的方法。谢谢! – Luigi

2

使用Enumerable#count与块。

[1,2,3,4,5,6,7,8,9,10].count { |val| val <= 6 } 
[1,2,3,4,5,6,7,8,9,10].count { |val| val == 7 || val == 8 } 
[1,2,3,4,5,6,7,8,9,10].count { |val| val > 8 } 
+0

循环三次? – AshwinKumarS

+0

@ 0v3rc10ck3d有多种方法可以做到这一点。 – squiguy

+0

当然不止一种方式。最快/效率最高的将是最有趣的方法;) – AshwinKumarS

0

更有趣,国际海事组织,是回答@路易吉与(不包含分号)一个语句的三个问题。这里有两种方法可以做到这一点:

a = [1,2,3,4,5,6,7,8,9,10] 

a.inject([0,0,0]) {|arr,i| [arr[0]+(i<7 ? 1:0), arr[1]+((i>6 and i<9) ? 1:0), arr[2]+(i>8 ? 1:0)]} 
a.slice_before(7).to_a.map {|arr| arr.slice_before(9).to_a}.flatten(1).map(&:size) 
    # => [6, 2, 2] 

编辑:另外,通过@ staafl的回答启发:

arr.group_by {|e| (e+1)/2-4<=>0}.values.map(&:size) 

您能否提供其他人呢?

0

如何:

>> hash = Hash.new(0) 
>> arr = [1,2,3,4,5,6,7,8,9,10] 
>> arr.each { |e| hash[(e-7.5).truncate<=>0]+=1 } 
>> hash 
=> {-1=>6, 0=>2, 1=>2} 

甚至更​​简洁:

>> arr = [1,2,3,4,5,6,7,8,9,10] 
>> arr.each_with_object(Hash.new(0)) { |e,h| h[(e-7.5).truncate<=>0]+=1 } 
=> {-1=>6, 0=>2, 1=>2} 
+1

这些帖子非常让人大开眼界......我是红宝石新手,看到用各种方式完成某件事情都是令人难以置信的。 – Luigi

+1

聪明!当然,'.values' => [6,2,2]。您也可以将块写为'{| e,h | h [(e + 1)/ 2-4 <=> 0] + = 1}'。 –

+0

@CarySwoveland,我相信'.values'的顺序是不确定的。如果需要数组,我们可能应该使用'.values_at(-1,0,1)'使其明确,或者'.values_at(* - 1..1)'如果我们聪明:-) – staafl