2010-06-12 3 views
11

MISE À JOUR 2: Pour la postérité, voilà comment je suis installé à le faire (grâce à l'entrée de Jorg):Déclarant une gamme entière à l'étape = 1 dans Ruby

100.step(2, -2) do |x| 
    # my code 
end 

(Évidemment, il y a beaucoup de façons de le faire, mais il semble que c'est le plus « Ruby » façon de le faire, et c'est exactement ce que je cherchais)


MISE à JOUR. OK, donc ce que je recherchais pour était step:

(2..100).step(2) do |x| 
    # my code 
end 

Mais il s'est avéré que je n'étais pas 100% disponible dans ma question initiale. Je veux réellement parcourir cette gamme à l'envers. À ma grande surprise, une étape négative n'est pas légale.

(100..2).step(-2) do |x| 
    # ArgumentError: step can't be negative 
end 

Alors: Comment faire cela en arrière?


Hé les gars, je suis complètement nouveau à Ruby, alors soyez gentil. Dites que je veux parcourir la gamme des nombres pairs de 2 à 100; comment ferais-je cela?

Il est évident que je pourrait faire:

(2..100).each do |x| 
    if x % 2 == 0 
     # my code 
    end 
end 

Mais, de toute évidence (encore une fois), ce serait assez stupide.

Je sais que je pouvais faire quelque chose comme: (?)

i = 2 
while i <= 100 
    # my code 
    i += 2 
end 

Je crois que je pourrais aussi écrire ma propre classe personnalisée qui fournit sa propre méthode each. Je suis presque sûr que ce serait exagéré, cependant.

Je suis intéressé par deux choses:

  1. Est-il possible faire cela avec une certaine variation de la syntaxe standard de la gamme (à savoir (x..y).each)?
  2. Quoi qu'il en soit, quelle serait la "méthode Ruby" la plus idiomatique de l'accomplir (en utilisant une gamme ou autre)? Comme je l'ai dit, je suis nouveau à la langue; Donc tout conseil que vous pouvez offrir sur la façon de faire les choses dans un style Ruby plus typique serait très apprécié.

Répondre

19

Vous ne pouvez pas déclarer un Range avec une "étape". Les rangs n'ont pas de pas, ils ont simplement un début et une fin.

Vous pouvez certainement itérer sur une Range par étapes, par exemple comme ceci:

(2..100).step(2).reverse_each(&method(:p)) 

Mais si tout ce que vous voulez est itérer, alors qu'est-ce que vous avez besoin du Range pour en premier lieu? Pourquoi ne pas simplement itérer?

100.step(2, -2, &method(:p)) 

Cela a l'avantage que, contrairement à reverse_each il n'a pas besoin de générer un tableau intermédiaire.

+0

Nice. Exactement ce dont j'avais besoin - et merci aussi de clarifier ma terminologie. Éclairci beaucoup! –

+0

@ Jörg aucune idée comment vous avez fini avec la dernière déclaration? Les documents pour l'étape ne mentionnent qu'un seul argument, alors je me demandais comment vous aviez trouvé votre façon de résoudre ce problème de façon succincte. –

+0

@n_x_l: Je ne suis pas sûr de ce que vous regardez, le paramètre 'step' est [clairement documenté] (http://Ruby-Doc.Org/core-2.1.1/Numeric.html#method-i -étape). Les documents les plus anciens que j'ai pu trouver étaient ceux de Ruby 1.8.6 et il [était déjà là] (http://Ruby-Doc.Org/core-1.8.6/Numeric.html#method-i-step) à l'époque en 2007. –

3

Cette question répond à la vôtre: about ruby range?

(2..100).step(2) do |x| 
    # your code 
end 
+0

C'est simple, hein? Merci! –

+0

Alors, comment pourrais-je le faire à l'envers? –

1

J'ai eu problème similaire voici les différentes façons je trouve à faire la même chose SIMPLE je pas à la fin, car il a permis incréments négatifs et fractionnels et j'avais aucune condition, autre que les limites de chercher

case loop_type 

    when FOR 
     # doen't appear to have a negative or larger than 1 step size! 
     for kg in 50..120 do 
     kg_to_stones_lbs(kg) 
     end 

    when STEP 
     120.step(70,-0.5){ |kg| 
     kg_to_stones_lbs(kg) 
     } 

    when UPTO 
     50.upto(120) { |kg| 
     kg_to_stones_lbs(kg) 
     } 

    when DOWNTO 
     120.downto(50){ |kg| 
     kg_to_stones_lbs(kg) 
     } 

    when RANGE 
     (50..120).reverse_each{ |kg| 
     kg_to_stones_lbs(kg) 
     } 

    when WHILE 
     kg = 120 
     while kg >= 50 
     kg_to_stones_lbs(kg) 
     kg -= 0.5 
     end 
    end 

O/P:

92,0 kg - 14st 7lbs

91,5 kg - 14st 6lbs

91,0 kg - 14st 5Kgs

90,5 kg - 14st 4lbs

90,0 kg - 14st 2lbs

89,5 kg - 14st 1lbs

89,0 kg - 14st 0Kgs

88,5 kg - 13st 13lbs

88,0 kg - 13st 12lbs

Questions connexes