What is the most beautiful way to break a larger range into smaller non overlapping ranges?
range = 1..375
Desired Output:
1..100
101..200
201..300
301..375
You can use #each_slice
in combination with #map
:
(1..375).each_slice(100).map { |a,*,b| (a..b) }
#=> [1..100, 101..200, 201..300, 301..375]
The following may not be the most elegant solution but it is designed to be relatively efficient, by avoiding the creation of temporary arrays.
def divide_range(range, sz)
start = range.begin
(range.size/sz).times.with_object([]) do |_,arr|
arr << (start..start+sz-1)
start += sz
end.tap { |arr| (arr << (start..range.end)) if start < range.end }
end
divide_range(1..375, 100)
#=> [1..100, 101..200, 201..300, 301..375]
divide_range(1..400, 100)
#=> [1..100, 101..200, 201..300, 301..400]
divide_range(50..420, 50)
#=> [50..99, 100..149, 150..199, 200..249, 250..299, 300..349,
# 350..399, 400..420]
n = 1_000_000_000_000
divide_range(1..n, n/2)
#=> [1..500000000000, 500000000001..1000000000000]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With