Ruby - Ranges
A range represents an interval, a set of values with a beginning and an end. Values of a range can be numbers, characters, strings or objects. It is constructed using double dot (..) operator, triple dot (...) operator or ::new method. It provides flexibility to the code and reduce the size of code.
Ruby supports ranges to be used in a variety of ways.
- Ranges as Sequences
- Ranges as Conditions
- Ranges as Intervals
Ranges as Sequences
The most natural way to use ranges in Ruby is to produce successive values in the sequence. Sequence has a start point, an end point, and a way to produce successive values in the sequence. There are three most commonly used method for constructing ranges.
- (..) operator : Creates a range from start point to end point inclusive.
- (...) operator : Creates a range from start point to end point exclusive.
- ::new method : Creates a range from start point to end point.
#(..) operator (-1..-5) #=> [] (-5..-1) #=> [-5, -4, -3, -2, -1] (1..5) #=> [1, 2, 3, 4, 5] ('a'..'e') #=> ["a", "b", "c", "d", "e"] #(...) operator (-1...-5) #=> [] (-5...-1) #=> [-5, -4, -3, -2] (1...5) #=> [1, 2, 3, 4] ('a'...'e') #=> ["a", "b", "c", "d"] #new operator - Syntax: new(begin, end, exclude_end = false) Range.new(-1,-5) #=> [] Range.new(-5,-1) #=> [-5, -4, -3, -2, -1] Range.new(1,5) #=> [1, 2, 3, 4, 5] Range.new('a','e') #=> ["a", "b", "c", "d", "e"]
When used as an iterator, ranges return each value in the sequence. Consider the example below where to_a method is used to convert ranges into array.
range1 = (1..5).to_a range2 = ("abc".."abg").to_a range3 = (100...105).to_a range4 = Range.new("A", "E").to_a #displaying the result puts "#{range1}" puts "#{range2}" puts "#{range3}" puts "#{range4}"
The output of the above code will be:
[1, 2, 3, 4, 5] ["abc", "abd", "abe", "abf", "abg"] [100, 101, 102, 103, 104] ["A", "B", "C", "D", "E"]
Ranges implement methods that let a user to iterate over them and test their contents in a number of ways. Consider the example below.
MyRange = 1..8 #checking the content retval = MyRange.include?(5) puts "MyRange contains 5?: #{retval}" #getting the minimum value retval = MyRange.min puts "MyRange minimum value: #{retval}" #getting the maximum value retval = MyRange.max puts "MyRange maximum value: #{retval}" #slicing the ranges retval = MyRange.select {|i| i < 5 } puts "MyRange selected: #{retval}" retval = MyRange.reject {|i| i < 5 } puts "MyRange rejected: #{retval}" #iterating over the range puts "MyRange contains:" MyRange.each do |i| puts i end
The output of the above code will be:
MyRange contains 5?: true MyRange minimum value: 1 MyRange maximum value: 8 MyRange selected: [1, 2, 3, 4] MyRange rejected: [5, 6, 7, 8] MyRange contains: 1 2 3 4 5 6 7 8
Ranges as Conditions
Ranges can also be used to define conditional expressions. Consider the example below where conditional expressions are defined using ranges in a case statement.
marks = 55 grade = case marks when 0..35 then "Fail" when 36..50 then "Grade D" when 51..65 then "Grade C" when 66..80 then "Grade B" when 81..100 then "Grade A" else "Invalid Score" end puts grade
The output of the above code will be:
Grade C
Ranges as Intervals
Ranges can also be used to defined intervals to check that the given value falls within the interval or not. It is represented by equality operator(===).
i = 55 if((1..50) === i) puts "#{i} lies between 1 and 50." elsif((51..100) === i) puts "#{i} lies between 51 and 100." else puts "#{i} do not lie between 1 and 100." end
The output of the above code will be:
55 lies between 51 and 100.