Intervalos representam um intervalo entre dois valores.
Os tipos mais comuns que dão suporte a intervalos são Integer e String.
Eles podem ser usados para muitas coisas, como criar uma coleção rapidamente, fatiar strings, verificar se um valor está em um intervalo e iterar.
Eles são criados com o operador de intervalo .. ou ... (inclusivo e 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]
O motivo de existirem dois operadores de intervalo é permitir criar intervalos que incluem ou excluem o valor final, o que pode ser útil, por exemplo, ao trabalhar com índices que começam em zero.
Também é possível criar intervalos usando o construtor Range, new.
Range.new(1, 5) # A range containing 1, 2, 3, 4, 5
Quando você cria um intervalo em Ruby com os operadores .. ou ... e quer chamar um método nele, precisa envolver o intervalo entre parênteses.
Isso acontece porque, caso contrário, o método será chamado no segundo argumento do operador de intervalo.
(1..5).sum # => 15
1..5.sum # => Error: undefined method `sum' for 5:Integer (NoMethodError)
Quando você quer fatiar uma string, pode usar o operador de intervalo para obter uma substring. Ou seja, criando um intervalo com o índice inicial e o final da substring.
"Hello World"[0..4] # => "Hello"
"Hello World"[6..10] # => "World"
Você também pode usar índices negativos para pegar a substring a partir do fim da string.
"Hello World"[-5..-1] # => "World"
"Hello World"[6..-4] # => "Wo"
Os intervalos têm, sim, um conjunto de métodos que podem ser usados para trabalhar com eles. Por exemplo, esses métodos podem ser usados para obter a soma de todos os valores do intervalo ou verificar se o intervalo inclui um valor.
| Método | Descrição | Exemplo |
|---|---|---|
sum |
Retorna a soma de todos os valores do intervalo | (1..5).sum # => 15 |
size |
Retorna o tamanho do intervalo | (1..5).size # => 5 |
include? |
Retorna true se o intervalo inclui o valor dado; caso contrário, false
|
(1..5).include?(3) # => true |
Um intervalo pode ser sem fim e sem início.
Um intervalo sem fim ou sem início tem o valor inicial ou final igual a nil, mas, ao definir o intervalo, o nil pode ser omitido.
Usar intervalos sem início e sem fim é útil quando você quer, por exemplo, fatiar uma string desde o início ou até o fim.
"Hello World"[0..] # => "Hello World"
"Hello World"[4..] # => "o World"
"Hello World"[..5] # => "Hello "
Se não for usado em uma coleção, o intervalo sem fim pode gerar uma sequência sem fim, caso não seja usado com cuidado.
Strings também podem ser usadas em intervalos e permitem obter um intervalo de strings entre duas strings. O comportamento pode ser um pouco inesperado com certas strings, então use com cuidado.
("aa".."az").to_a # => ["aa", "ab", "ac", ..., "az"]
Como entusiasta de xadrez, você gostaria de escrever sua própria versão do jogo. Sim, talvez já existam por aí muitas implementações de xadrez disponíveis online, mas a sua vai ser única!
Você começa implementando um sistema básico de movimento para as peças.
O jogo de xadrez será disputado em um tabuleiro com 8 casas de largura e 8 casas de comprimento. As casas são identificadas por uma letra e um número.
O jogo vai precisar armazenar as fileiras do tabuleiro. As fileiras são as linhas do tabuleiro e são numeradas de 1 a 8.
O jogo também vai precisar armazenar as colunas do tabuleiro. As colunas do tabuleiro são identificadas pelas letras A a H.
Defina as constantes Chess::RANKS e Chess::FILES, que armazenam o intervalo de fileiras e colunas, respectivamente.
Chess::RANKS
# => 1..8
Chess::FILES
# => 'A'..'H'
O jogo vai precisar verificar se uma casa é válida. Uma casa é válida se a fileira e a coluna estiverem dentro dos intervalos de fileiras e colunas.
Defina o método Chess.valid_square?, que recebe os argumentos rank, que contém um inteiro da fileira, e file, que contém um caractere da coluna.
O método deve retornar true se a fileira e a coluna estiverem dentro dos intervalos de fileiras e colunas e retornar false caso contrário.
Chess.valid_square?(1, 'A')
# => true
O jogo vai precisar obter o apelido do jogador. O apelido é formado pelos 2 primeiros caracteres do primeiro nome do jogador e pelos 2 últimos caracteres do sobrenome. O apelido deve estar em letras maiúsculas.
Defina o método Chess.nickname, que recebe os argumentos first_name, que contém uma string com o primeiro nome do jogador, e last_name, que contém uma string com o sobrenome do jogador.
O método deve retornar o apelido do jogador como uma string em maiúsculas.
Chess.nickname("John", "Doe")
# => "JOOE"
O jogo vai precisar criar uma mensagem para um movimento, dizendo qual jogador se moveu para qual casa. A mensagem deve usar o apelido do jogador e a casa para onde ele se moveu. O jogo também precisa determinar se o movimento é válido, verificando se a coluna e a fileira da casa estão dentro dos intervalos de colunas e fileiras.
Se o movimento for válido, a mensagem deve ser: "{nickname} moved to {square}"
Se o movimento for inválido, a mensagem deve ser: "{nickname} attempted to move to {square}, but that is not a valid square"
Defina o método Chess.move_message, que recebe os argumentos first_name, que contém uma string com o primeiro nome do jogador, last_name, que contém uma string com o sobrenome do jogador, e square, que contém uma string com a casa para onde o jogador se moveu.
O método deve retornar a mensagem do movimento como uma string.
Chess.move_message("John", "Doe", "A1")
# => "JOOE moved to A1"
Crie sua conta no Exercism para aprender e dominar Ruby com 21 conceitos121 exercícios e mentoria humana de verdade, tudo de graça.