Pregunta ¡Declarando un entero Rango con paso! = 1 en Ruby


ACTUALIZACIÓN 2: Para la posteridad, así es como me he decidido a hacerlo (gracias a la contribución de Jorg):

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

(Obviamente hay muchas formas de hacer esto, pero parece que esta es la forma más "Ruby" de hacerlo, y eso es exactamente lo que estaba buscando).


ACTUALIZAR: OK, entonces lo que estaba buscando era step:

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

Pero resulta que no fui 100% cercano en mi pregunta original. De hecho, quiero iterar sobre este rango hacia atrás. Para mi sorpresa, un paso negativo no es legal.

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

Asi que: ¿Cómo hago esto al revés?


Hola chicos, estoy completamente nuevo a Ruby, así que sé gentil.

Digamos que quiero iterar sobre el rango de números pares de 2 a 100; ¿Como podría hacerlo?

Obviamente yo podría hacer:

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

Pero, obviamente (de nuevo), eso sería bastante estúpido.

Sé que podría hacer algo como:

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

Creo que también podría escribir mi propia clase personalizada que proporciona su propio each método (?). Estoy casi seguro de que sería excesivo, sin embargo.

Estoy interesado en dos cosas:

  1. Lo es posible para hacer esto con alguna variación de la sintaxis de Rango estándar (es decir, (x..y).each)?
  2. De cualquier manera, ¿cuál sería la "forma Ruby" más idiomática de lograr esto (usando un Alcance o de otro modo)? Como dije, soy nuevo en el lenguaje; así que cualquier orientación que pueda ofrecer sobre cómo hacer las cosas en un estilo Ruby más típico sería muy apreciada.

13
2018-06-12 19:06


origen


Respuestas:


No puedes declarar un Range con un "paso". Los rangos no tienen pasos, simplemente tienen un principio y un final.

Ciertamente puedes iterar sobre un Range en pasos, por ejemplo, como este:

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

Pero si todo lo que quiere es iterar, ¿qué necesita? Range para en primer lugar? ¿Por qué no solo iterar?

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

Esto tiene el beneficio adicional que a diferencia reverse_each no necesita generar una matriz intermedia.


21
2018-06-12 21:29



Esta pregunta responde a la tuya sobre el rango de rubí?

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

3
2018-06-12 19:08



Tuve un problema similar aquí son las diversas maneras en que encontré para hacer la misma cosa SIMPLE que utilicé al final porque permitía incrementos NEGATIVOS y FRACCIONARIOS y no tenía condiciones, aparte de los límites que debía buscar

  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.0kg - 14st 7lbs

91.5kg - 14st 6lbs

91.0kg - 14st 5lbs

90.5kg - 14st 4lbs

90.0kg - 14st 2lbs

89.5kg - 14st 1lbs

89.0kg - 14st 0lbs

88.5kg - 13st 13lbs

88.0kg - 13st 12lbs


1
2018-03-04 14:27