Skip to content

Instantly share code, notes, and snippets.

@jakebromberg
Last active January 28, 2018 17:12
Show Gist options
  • Save jakebromberg/1c54a09953435fc621bf2c996b628ec4 to your computer and use it in GitHub Desktop.
Save jakebromberg/1c54a09953435fc621bf2c996b628ec4 to your computer and use it in GitHub Desktop.
protocol Coalescable {
/// - Returns: One of the four cases:
/// - a new, combined instance
/// - nil, signalling the two cannot be combined
/// - `self`
/// - `other`
func coalesce(with other: Self) -> Self?
}
extension Sequence where Element: Coalescable {
func coalesce() -> [Element] {
return reduce(into: [], { (result, thisElement) in
if let lastElement = result.last,
let combinedElement = lastElement.coalesce(with: thisElement) {
result[result.endIndex - 1] = combinedElement
} else {
result.append(thisElement)
}
})
}
}
extension CountableClosedRange: Coalescable {
func coalesce(with other: CountableClosedRange<Bound>) -> CountableClosedRange<Bound>? {
if self.overlaps(other) {
return Swift.min(self.lowerBound, other.lowerBound)...Swift.max(self.upperBound, other.upperBound)
} else {
return nil
}
}
}
let ranges = [1...3, 2...4, 5...7, 6...8]
let actual = ranges.coalesce()
let expected = [1...4, 5...8]
assert(actual == expected)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment