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 rápidamente una colección, cortar strings, comprobar si un valor está dentro de un rango e iterar.
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]
La razón por la que existen dos operadores de rango es que permiten crear rangos que incluyen o excluyen el valor final, lo cual puede ser útil cuando, por ejemplo, trabajas con índices basados en cero.
Los rangos también se pueden crear usando el constructor Range, new.
Range.new(1, 5) # A range containing 1, 2, 3, 4, 5
Cuando creas un rango en Ruby con los operadores de rango .. o ... y quieres llamar a un método sobre el rango, necesitas encerrar el rango entre paréntesis.
Esto se debe a que, de lo contrario, el método se llamará sobre el segundo argumento del operador de rango.
(1..5).sum # => 15
1..5.sum # => Error: undefined method `sum' for 5:Integer (NoMethodError)
Cuando quieres cortar un string, puedes usar el operador de rango para obtener una subcadena. Es decir, creando un rango con el índice de inicio y de fin 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"
Los rangos tienen un conjunto de métodos que puedes 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, de lo contrario false
|
(1..5).include?(3) # => true |
Un rango puede no tener final ni inicio.
En un rango sin final o sin inicio, el valor de inicio o de fin es nil, pero al definir el rango puedes omitir el nil.
Usar rangos sin inicio y sin final es útil cuando quieres, por ejemplo, cortar un string desde el principio o hasta el final.
"Hello World"[0..] # => "Hello World"
"Hello World"[4..] # => "o World"
"Hello World"[..5] # => "Hello "
Si no se usa sobre una colección, el rango sin final puede provocar una secuencia sin fin si no se usa con cuidado.
Los strings también se pueden usar en rangos y permiten obtener un intervalo de strings entre dos strings. Su comportamiento puede ser un poco inesperado con ciertos strings, así que úsalo con cuidado.
("aa".."az").to_a # => ["aa", "ab", "ac", ..., "az"]
Como aficionado al ajedrez, te gustaría escribir tu propia versión del juego. Sí, quizá ya haya muchas implementaciones de ajedrez disponibles en línea, ¡pero la tuya será única!
Empiezas implementando un sistema básico de movimiento para las piezas.
El juego de ajedrez se jugará en un tablero de 8 casillas de ancho y 8 casillas de largo. Las casillas se identifican con una letra y un número.
El juego tendrá que almacenar las filas del tablero. Las filas son las hileras del tablero y se numeran del 1 al 8.
El juego también tendrá que almacenar las columnas del tablero. Las columnas son las verticales del tablero y se identifican con las letras de la A a la H.
Define las constantes Chess::RANKS y Chess::FILES que almacenan el rango de filas y columnas respectivamente.
Chess::RANKS
# => 1..8
Chess::FILES
# => 'A'..'H'
El juego tendrá que verificar si una casilla es válida. Una casilla es válida si la fila y la columna están dentro de los rangos de filas y columnas.
Define el método Chess.valid_square? que recibe los argumentos rank, que contiene un entero de la fila, y file, que contiene un carácter de la columna.
El método debe devolver true si la fila y la columna están dentro de los rangos de filas y columnas, y devolver false en caso contrario.
Chess.valid_square?(1, 'A')
# => true
El juego tendrá que obtener el apodo del jugador. El apodo son los primeros 2 caracteres del nombre del jugador y los últimos 2 caracteres de su apellido. El apodo debe estar en mayúsculas.
Define el método Chess.nickname que recibe los argumentos first_name, que contiene un string con el nombre del jugador, y last_name, que contiene un string con el apellido del jugador.
El método debe devolver el apodo del jugador como un string en mayúsculas.
Chess.nickname("John", "Doe")
# => "JOOE"
El juego tendrá que crear un mensaje para un movimiento que indique qué jugador se movió a qué casilla. El mensaje debe usar el apodo del jugador y la casilla a la que se movió. El juego también tiene que determinar si el movimiento es válido verificando si la columna y la fila de la casilla están dentro de los rangos de columnas y filas.
Si el movimiento es válido, el mensaje debe ser: "{nickname} moved to {square}"
Si el movimiento no es válido, el mensaje debe ser: "{nickname} attempted to move to {square}, but that is not a valid square"
Define el método Chess.move_message que recibe los argumentos first_name, que contiene un string con el nombre del jugador, last_name, que contiene un string con el apellido del jugador, y square, que contiene un string con la casilla a la que se movió el jugador.
El método debe devolver el mensaje del movimiento como un string.
Chess.move_message("John", "Doe", "A1")
# => "JOOE moved to A1"
Regístrate en Exercism para aprender y dominar Ruby con 21 conceptos121 ejercicios y mentoría humana real, todo gratis.