Диапазоны


Диапазоны — это особый тип данных в Ruby, который является достаточно уникальным, поскольку далеко не в каждом языке он существует и достаточно полезный, диапазоны упрощают код.

Диапазон заключается в круглые скобки, и состоит из минимума и максимум, которые разделены двумя или тремя точками, ниже приведен простые примеры диапазонов:

Диапазон является самостоятельным типом данных, который принадлежит классу Range:

Диапазоны
(1..10).class #=> Range

(1..10) # соответствует последовательности от 1 до 10 включительно
(1...10) # соответствует последовательности от 1 до 10, не включая 10
('a'..'z') # соответствует всему латинскому алфавиту.


Диапазоны не богаты на методы и методы для диапазонов используются достаточно редко, за исключением метода to_a, который преобразует диапазон в массив.


#to_a преобразует диапазон в массив, пример:

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


#min и #first, #max и #last — данные методы возвращают соответственно начало диапазона и его конец, пример:

(1...100).min #=> 1
(1...100).max #=> 99
(1..100).max #=> 100
(1..100).first #=> 1
(1..100).last #=> 100
('a'..'z').min #=> "a"
('a'..'z').max #=> "z"


Между #min и #first, а также #max и #last существует маленькое, но очень важное различие, незнание которого может привести к ошибкам в коде! Это различие проявляется тогда, когда используются обратные диапазоны, пример:

(1..100).first #=> 1
(1..100).min #=> 1
(100..1).min #=> nil
(100..1).first #=> 100

(1..100).max #=> 100
(1..100).last #=> 100
(100..1).max #=> nil
(100..1).last #=> 1


#min и #max при обратных диапазонах возвращают значение nil, этим можно пользоваться, когда вам необходимо узнать, диапазон прямой или обратный, во всех остальных случаях я бы рекомендовал использовать методы #last и #first, если разумеется нет ограничения на то, каким должен быть диапазон (обязательно ли он должен быть прямым?).

#include? и #member? — методы синонимы, которые принимают в качестве аргумента число или буквенный символ и проверяют его вхождение в диапазон. Если буква или число входит в диапазон, то будет возвращено значение true, иначе false, пример:

(1..100000).include?(1) #=> true
(1..100000).include?(100001) #=> false
(1..100000).member?(100001) #=> false
('a'..'y').member?("c") #=> true
('a'..'y').member?("z") #=> false


#begin — метод идентичен методам #first и #min и возвращает первый элемент диапазона.

(2...100).begin #=> 2


#end — этот метод возвращает последний элемент диапазона, пример:

(1..100).end #=> 100
(1...100).end #=> 100
('a'..'z').end #=> "z"
('a'...'z').end #=> "z"

#exclude_end — данный метод возвращает true для диапазонов, которые не включают максимум (диапазоны с тремя точками) и false для диапазонов, которые включают максимум, пример:

(1..10).exclude_end? #=> false
(1...10).exclude_end? #=> true




Диапазоны очень полезны, например, они могут здорово помочь тогда, когда нам необходимо создать массив последовательных элементов:

(1..10).to_a #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


Представьте, что элементов не 10, а тысяча и вы поймете, что диапазоны действительно удобны. Разумеется, такой массив можно было бы создать при помощи цикла, однако это лишний, ухудшающий читабельность код!

Диапазоны очень удобны в использовании, с выражением case, пример:

a = 101
case a
when 1...50 then puts "0 < a < 50"
when 50...100 then puts "50 <= a < 100"
when 100...150 then puts "100 100 <= a < 150


Диапазоны делаю код красивее и удобнее для чтения!