Skip to content

Instantly share code, notes, and snippets.

@danveloper
Created February 28, 2013 17:37
Show Gist options
  • Save danveloper/5058557 to your computer and use it in GitHub Desktop.
Save danveloper/5058557 to your computer and use it in GitHub Desktop.
collapse overlapping ranges in list
List.metaClass.collapse = {->
def start,end
def reverse = delegate[0]?.getAt(0)-delegate[0]?.getAt(-1) > 0
def expanded = delegate.flatten().unique().sort()
def result = (reverse ? expanded.reverse() : expanded).inject([]) { l, n ->
start = start == null ? n : start
end = end == null ? n : end
if ((reverse?n+1:n-1)==end) {
end = n
} else if (start != end) {
l << (start..end)
start=n
end=n
}
l
} << (start..end)
result
}
assert [ 12..13, 17..19, 18..22, 17..19, 22..23, 19..20 ].collapse() == [ 12..13, 17..23 ]
assert [ -2..3, -5..-2 ].collapse() == [-5..3]
assert [ 3..1, 1..5 ].collapse() == [5..1] // descending order initially, so descend wholly
assert [ 1..5, 3..1 ].collapse() == [1..5]
assert [ 1..5, 3..1, -1..-4 ].collapse() == [-4..-1, 1..5] // ascending order initially, so ascend across the collection
assert [ 1..5, -6..-4, 3..1, -1..-4 ].collapse() == [-6..-1, 1..5] // mixed-direction provided, ascend in finality
assert [ 1..3, 5..6, 3..5 ].collapse() == [1..6]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment