Ranges
Bean Cart runs a happy hour from 14 to 16 o'clock, and gives a bulk discount for orders of 10 to 19 cups. Both are spans of values with a start and an end. Ruby has a type for exactly that, the Range, and it saves you from writing hour >= 14 && hour <= 16 over and over.
The rule
Two dots include the end; three dots exclude it.
(1..5).to_a # => [1, 2, 3, 4, 5]
(1...5).to_a # => [1, 2, 3, 4]A handy way to remember it: the extra dot pushes the last value out.
Ranges are objects with useful methods:
happy_hour = 14..16
happy_hour.include?(15) # => true
happy_hour.include?(17) # => false
happy_hour.cover?(15.5) # => true (is it between the ends?)
(10..19).size # => 10
(1...10).size # => 9
happy_hour.min # => 14
happy_hour.max # => 16They are not only for integers. Letters and other comparable values work too:
("a".."e").to_a # => ["a", "b", "c", "d", "e"]You can walk through a range with a block, or in steps:
(1..3).each { |n| puts "Order #{n}" }
(0..20).step(5).to_a # => [0, 5, 10, 15, 20]Ranges can also be open-ended. (20..) means "20 or more", and (..9) means "up to and including 9". These are great for thresholds:
bulk = (20..)
bulk.include?(35) # => trueRanges also slice arrays by position: with queue = ["latte", "tea", "mocha", "chai"], queue[1..2] is ["tea", "mocha"], and queue[1..] is everything from index 1 on.
Always wrap a range in parentheses before calling a method on it. 1..5.to_a is read as 1..(5.to_a) and fails.
The shortcut
Count the dots, then check the last value. Two dots: the last value is in. Three dots: it is out. For the size of a whole-number range, it is last - first + 1 with two dots, and last - first with three.
Small orders
1 to 9 cups:
(1..9), or the same thing as(1...10).
Drills
Answer fast — trust the rule.
What is (3...6).to_a?
What does (14..16).include?(16) return?
How many values are in (5..12)?
Which range means "20 or more"?
With queue = ["latte", "tea", "mocha", "chai"], what is queue[0...2]?
Remember
- Two dots include the end; three dots exclude it.
- Count the dots, then check the last value; wrap ranges in parentheses before calling methods.
- Trap:
(1...10)stops at 9, and1..5.to_ais parsed the wrong way.
