iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Ranges

A range is two endpoints and a direction. 1..5 is inclusive; 1...5 excludes the end. Ranges work as iterators, as case-statement matchers, and as slice indices.

Range patterns

EXAMPLE
# Build
r1 = 1..5            # 1, 2, 3, 4, 5 — inclusive
r2 = 1...5            # 1, 2, 3, 4 — exclusive end
letters = 'a'..'e'    # ranges work on anything that implements <=> + succ

# Iterate
(1..5).each { |i| puts i }
(1...5).map { |i| i * i }   # [1, 4, 9, 16]
(1..1000).step(2).to_a       # odd numbers 1..999

# Test membership
(1..10).cover?(5)         # true — O(1) on integer ranges
(1..10).include?(5)       # true — O(n) on arbitrary ranges
('a'..'z').cover?('f')

# Case / when with ranges
case age
when 0..12   then puts 'kid'
when 13..17  then puts 'teen'
when 18..64  then puts 'adult'
else              puts 'senior'
end

# Slice arrays / strings
[10, 20, 30, 40, 50][1..3]      # [20, 30, 40]
[10, 20, 30, 40, 50][1...3]     # [20, 30]
'hello world'[0..4]              # 'hello'

# Endless / beginless (Ruby 2.6+)
arr[2..]                          # everything from index 2 onwards
arr[..3]                          # everything up to index 3 inclusive

# Sample / random
(1..100).to_a.sample              # random integer 1..100
rand(1..100)                       # same, idiomatic

# Lazy — for huge ranges
(1..Float::INFINITY).lazy.map { |n| n * n }.first(5)   # [1, 4, 9, 16, 25]

Why it matters

Range + case is the most readable way to bucket numeric input. Reach for it whenever you find yourself writing elsif x < N && x >= M chains.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
(1..5).each { |i| puts i }
(1...5).to_a       # [1,2,3,4] — exclusive end
Try it Yourself »

Discussion

Loading…