2013-10-12 2 views
0

J'ai un tableau:Ruby compte gamme de valeurs dans un tableau

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

et je dois compter trois choses distinctes.

1) Toutes les valeurs inférieures ou égales à 6.

2) Toutes les valeurs sont égales à 7 ou 8.

3) Toutes les valeurs supérieures à 8.

Quelle est la meilleure façon de le faire sans compter les valeurs individuelles et les ajouter tous ensemble?

+0

Vous voulez dire _add_ ou _count frequency_? – zeantsoi

+0

boucle une fois dans le tableau. Et faire toutes les opérations dans cela. – AshwinKumarS

Répondre

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

Cela semble être le moyen le plus propre de trouver les valeurs dont j'ai besoin. Merci! – Luigi

2

Utilisez Enumerable#count avec un bloc.

[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

Boucle à travers trois fois ?? – AshwinKumarS

+0

@ 0v3rc10ck3d Il y a plusieurs façons de le faire. – squiguy

+0

bien sûr plus d'une façon. Le plus rapide/le plus efficace ne serait-il pas le moyen le plus intéressant;) – AshwinKumarS

0

Plus intéressant, imo, est de répondre à trois questions @ Luigi avec une seule instruction (ne contenant pas de points-virgules). Voici deux façons de le faire:

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] 

Edit: une autre, inspirée par la réponse de @ staafl:

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

Pouvez-vous suggérer d'autres?

0

Que diriez-vous ceci:

>> 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} 

Ou encore plus succincte:

>> 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

Ces messages sont assez ouverture des yeux .... Je suis nouveau à ruby ​​et voir toutes les façons de faire quelque chose est incroyable. – Luigi

+1

Clever! Et, bien sûr, '.values' => [6,2,2]. Vous pouvez aussi écrire le bloc comme '{| e, h | h [(e + 1)/2-4 <=> 0] + = 1} '. –

+0

@CarySwoveland, je crois que l'ordre de '.values' est indéfini. Si un tableau est requis, nous devrions probablement utiliser '.values_at (-1,0,1)' pour le rendre explicite, ou '.values_at (* - 1..1)' si nous étions intelligents :-) – staafl

Questions connexes