DEV Community

loading...
Cover image for Ranges in Ruby

Ranges in Ruby

eminarium profile image Merdan Durdiyev ・4 min read

Welcome

Welcome back, dear friends! Welcome newcomers, coders, and enthusiasts! Today we are going to have a look at how to use Ranges in our beloved Ruby PL. To note first, Ranges are a data structure that is not present in many programming languages. It became popular in modern programming languages and it just represents a slice of a previously defined and ordered set of elements.

What is a Range?

We come across Ranges in many daily situations. For instance:

  • Month range: between “April — September”
  • Number range: between “5–8”
  • Letter range: between “d — h”

The existence of such a class releases us from the burden of creating an Array of ordered elements in some cases. If we need a slice of elements, say from 20-th to 30-th one, we don’t have to define them as Array. Listing all the required elements will take time. In the examples above, we are free from defining those letters, numbers, months, and month dates as separate Arrays. We just show the starting element and ending element and separate it as a Range.

To define Ranges, we put dots between the starting and ending elements. Here is what they mean:

  • (3..8): “two dots”, includes the ending element, (3, 4, 5, 6, 7, 8)
  • (3…8): “three dots”, does not include the ending element, (3, 4, 5, 6, 7)

Here are some examples of these:

(1..5)        #==> 1, 2, 3, 4, 5
(1...5)       #==> 1, 2, 3, 4
('a'..'d')    #==> 'a', 'b', 'c', 'd'
Enter fullscreen mode Exit fullscreen mode

Create a new Range

To create a new Range we just write the starting and ending element values and put two or three dots between them. We have already covered what those dots mean in the section above. To print the Range you can use the “to_a” method. This way you convert the Range to an Array.

(-1..-5).to_a      #=> []
(-5..-1).to_a      #=> [-5, -4, -3, -2, -1]
('a'..'e').to_a    #=> ["a", "b", "c", "d", "e"]
('a'...'e').to_a   #=> ["a", "b", "c", "d"]
Enter fullscreen mode Exit fullscreen mode

The interesting part of this is that you can do something like this:

range1 = ('bar'..'bav').to_a

puts "#{range1}"
# Output: ["bar", "bas", "bat", "bau", "bav"]
Enter fullscreen mode Exit fullscreen mode

As you see, Ruby PL automagically understands what values to insert in between. Bravo “Ruby”!

Range methods

There are some widely used methods with Ranges. Here they are:

  • include? : Returns “true” or “false”. Checks whether the requested element is present in the given Range.
  • max: Returns the maximum element in the Range.
  • min: Returns the minimum element in the Range.
  • reverse: Reverses the Range.

Let’s see some examples of how to use them:

# 'include?' method
puts ("a".."z").include?("g")   #=> true
puts ("a".."z").include?("A")   #=> false
puts ("a".."z").include?("cc")  #=> false

digits = 0..9
puts digits.include?(5) # true

# 'max' and 'min' methods
puts (10..20).max    #=> 20
puts (10..20).min    #=> 10

# 'reverse' method
puts (1..5).to_a.reverse

# 'first' method
(10..20).first     #=> 10
(10..20).first(3)  #=> [10, 11, 12]

# 'last' method
(10..20).last      #=> 20
(10...20).last     #=> 20
(10..20).last(3)   #=> [18, 19, 20]
(10...20).last(3)  #=> [17, 18, 19]
Enter fullscreen mode Exit fullscreen mode

Iterating over Range elements

As we already have seen in Arrays and Hashes, we can iterate through them using the ‘each’ method. It means we can also use that method for iterating over a Range. We can use this code snippet to print all the elements of a Range:

numbers = (15..20) 

numbers.each do |num|
  puts "Next number = #{num}"
end

# Next number = 15
# Next number = 16
# Next number = 17
# Next number = 18
# Next number = 19
# Next number = 20
Enter fullscreen mode Exit fullscreen mode

Exactly the same way, you can iterate over a letter Range.

Using Ranges in conditional checks

If we take a look at how we use Ranges in conditionals, we can recognize that they are mostly used in the “case-when” conditional structure. To be precise, we check if the subject item is in between the given Range. In other programming languages, the same conditional structure is otherwise called ‘switch-case’, and using that we can only check for equality to a certain value, not an inclusion in the Range. But in Ruby, we can check if a subject value falls in the given Range. For instance:

grade = 70

result = case grade
   when 0...50 then "Sorry, you failed!"
   when 51..60 then "That was hard, but you passed!"
   when 61..70 then "Not bad!"
   when 71..80 then "Satisfactory!"
   when 81..100 then "Great, you are a Superman!"
   else "Incorrect grade !"
end

puts result
Enter fullscreen mode Exit fullscreen mode

Conclusion

Dear friends, here we came to the end of the article. One thing we have to remind ourselves once more is that the “Range” class is present in not so many programming languages. This shows to what extend Ruby developers thought of software developers' comfort.
Ruby philosophy has such a point: “Developer happiness first”. This, once again underlines that Ruby is for human beings :-)
So much comfort is provided for us. So let’s learn the programming language that puts developers' happiness first.
See you in the next article. Goodbye!

Discussion

pic
Editor guide