Ra

Rangos en Ruby

1 ejercicio

Acerca de Rangos

Los rangos representan un intervalo entre dos valores. Los tipos más comunes que admiten rangos son Integer y String. Se pueden usar para muchas cosas, como crear una colección rápidamente, extraer subcadenas, comprobar si un valor está dentro de un rango y la iteración. Se crean con el operador de rango .. o ... (inclusivo y exclusivo, respectivamente).

1..5  # => 1..5
1...5 # => 1...5

(1..5).to_a # => [1, 2, 3, 4, 5]
(1...5).to_a # => [1, 2, 3, 4]

El motivo de tener dos operadores de rango es permitir crear rangos que incluyan o excluyan el valor final, lo cual puede ser útil, por ejemplo, al trabajar con índices que empiezan en cero.

Los rangos también se pueden crear usando el inicializador de Range.

Range.new(1, 5) # A range containing 1, 2, 3, 4, 5
Note

Al crear un rango en Ruby con los operadores de rango .. o ... y querer llamar a un método sobre el rango, tienes que envolver el rango entre paréntesis. Esto se debe a que, de lo contrario, el método se llamaría sobre el segundo argumento del operador de rango.

(1..5).sum # => 15
1..5.sum # => Error: undefined method `sum' for 5:Integer (NoMethodError)

Obtener subcadenas

Cuando quieres extraer una subcadena de un string, puedes usar el operador de rango para obtenerla. Es decir, creando un rango con el índice inicial y final de la subcadena.

"Hello World"[0..4] # => "Hello"
"Hello World"[6..10] # => "World"

También puedes usar índices negativos para obtener la subcadena desde el final del string.

"Hello World"[-5..-1] # => "World"
"Hello World"[6..-4] # => "Wo"

Métodos de los rangos

Los rangos tienen un conjunto de métodos que se pueden usar para trabajar con ellos. Por ejemplo, estos métodos sirven para obtener la suma de todos los valores del rango o para comprobar si el rango incluye un valor.

Método Descripción Ejemplo
sum Devuelve la suma de todos los valores del rango (1..5).sum # => 15
size Devuelve el tamaño del rango (1..5).size # => 5
include? Devuelve true si el rango incluye el valor dado; en caso contrario, false (1..5).include?(3) # => true

Rangos sin fin y sin comienzo

Un rango puede ser sin fin y sin comienzo. En los rangos sin fin o sin comienzo, su valor inicial o final es nil, pero al definir el rango se puede omitir el nil.

Usar rangos sin comienzo y sin fin resulta útil cuando quieres, por ejemplo, extraer una subcadena desde el principio o hasta el final.

"Hello World"[0..] # => "Hello World"
"Hello World"[4..] # => "o World"
"Hello World"[..5] # => "Hello "
Caution

Si no se usa sobre una colección, el rango sin fin puede provocar una secuencia infinita si no se utiliza con cuidado.

Rangos de strings

Los strings también se pueden usar en rangos y permiten obtener un intervalo de strings entre dos strings. Su comportamiento puede resultar algo inesperado con ciertos strings, así que úsalo con cuidado.

"aa".."az".to_a # => ["aa", "ab", "ac", ..., "az"]

Objetos personalizados en rangos

Advanced

Ruby te permite usar objetos personalizados en rangos. El requisito para ello es que el objeto implemente lo siguiente:

  • incluya el módulo Comparable
  • el método succ
  • el método <=>

Estos métodos hacen posible que el rango pueda iterar sobre el objeto y comparar los objetos del rango.

class Foo
  include Comparable

  attr_reader :value

  def initialize(value)
    @value = value
  end

  def succ
    Foo.new(value + 1)
  end

  def <=>(other)
    value <=> other.value
  end
end

(Foo.new(1)..Foo.new(5))
# => #<Foo:0x7f3552bebe70 @value=1>, #<Foo:0x7f3552bebe50 @value=2>, #<Foo:0x7f3552bebe40 @value=3>, #<Foo:0x7f3552bebe30 @value=4>, #<Foo:0x7f3552bebe20 @value=5>
Editar en GitHub El enlace se abre en una nueva ventana o pestaña

Aprende Rangos