Flyingbeaver
Flyingbeaver

Reputation: 375

Complete and order a list of ranges?

I have the following ranges:

(800..1200)
(800..1600)
(800..1700)
(800..1900)
(900..1500)
(1000..2000)
(2200..2300)

And want to get an array like this:

[(800..900), (900..1000), (1000..1200), (1200..1500), (1500..1600), (1600..1700), (1700..1900), (1900..2000), (2000..2200), (2200..2300)]

The expected array (ranges) is an ordered list of ranges, where ranges[n+1].min == ranges[n].max. We shouldn't have any gap between ranges.

I have succeeded to write code that does this, but it's a long list of if/else in a loop, and is not very readable. I was wondering if someone has any idea on how to do this more concisely?

Upvotes: 0

Views: 34

Answers (1)

Cary Swoveland
Cary Swoveland

Reputation: 110675

This should do it.

a = [(800..1200),  (800..1600), (800..1700), (800..1900),
     (900..1500), (1000..2000), (2200..2300)]
a.each_with_object([]) { |r,a| a << r.first << r.last }
 .uniq
 .sort
 .each_cons(2)
 .to_a
 .map { |a,b| a..b }
   #=> [800..900, 900..1000, 1000..1200, 1200..1500, 1500..1600,
   #    1600..1700, 1700..1900, 1900..2000, 2000..2200, 2200..2300]

Upvotes: 1

Related Questions