Currently, if you implement a recursion function, you would do something similar to this:
extension Array where Element: Comparable {
func search(for value: Element, in range: Range<Index>? = nil) -> Index? {
let range = range ?? startIndex..<endIndex
guard range.lowerBound < range.upperBound else { return nil }
let size = distance(from: range.lowerBound, to: range.upperBound)
let middle = index(range.lowerBound, offsetBy: size / 2)
if self[middle] == value {
return middle
} else if self[middle] > value {
return search(for: value, in: range.lowerBound..<middle)
} else {
return search(for: value, in: middle + 1..<range.upperBound)
}
}
}
// [2, 3, 4, 8].search(for: 7)
// [2, 3, 4, 8].binarySearch(for: 7, in: ???)
The range parameter is intended for internal use, that's for recursive call, and to hide this from out world callers, something similar to this can be done:
func search(for value: Element) -> Index? {
func binarySearch(for value: Element, in range: Range<Index>? = nil) -> Index? {
let range = range ?? startIndex..<endIndex
guard range.lowerBound < range.upperBound else { return nil }
let size = distance(from: range.lowerBound, to: range.upperBound)
let middle = index(range.lowerBound, offsetBy: size / 2)
if self[middle] == value {
return middle
} else if self[middle] > value {
return binarySearch(for: value, in: range.lowerBound..<middle)
} else {
return binarySearch(for: value, in: middle + 1..<range.upperBound)
}
}
return binarySearch(for: value)
}
You may keep
binarySearch(for:in:)
out sidesearch(for:)
withprivate
keyword.
But, I had an idea, which I'm not sure if it's even possible, is that we introduce a new keyword that makes a parameter only visible for recursion. Which might look something similar to this:
private func binarySearch(for value: Element, @recursion in range: Range<Index>? = nil) -> Index? {
// implementation
}
What do you think? Is it even possible?