Swift: Binary search for standard array?

Peter71 picture Peter71 · Aug 9, 2015 · Viewed 16.9k times · Source

I have a sorted array and want to do binary search on it.

So I'm asking if something is already available in Swift library like sort etc.? Or is there a type independend version available?

Of course I could write it by my own, but I like to avoid reinventing the wheel again.

Answer

Vadim Yelagin picture Vadim Yelagin · Nov 12, 2015

Here's my favorite implementation of binary search. It's useful not only for finding the element but also for finding the insertion index. Details about assumed sorting order (ascending or descending) and behavior with respect to equal elements are controlled by providing a corresponding predicate (e.g. { $0 < x } vs { $0 > x } vs { $0 <= x } vs { $0 >= x }). The comment unambiguously says what exactly does it do.

extension RandomAccessCollection {
    /// Finds such index N that predicate is true for all elements up to
    /// but not including the index N, and is false for all elements
    /// starting with index N.
    /// Behavior is undefined if there is no such N.
    func binarySearch(predicate: (Element) -> Bool) -> Index {
        var low = startIndex
        var high = endIndex
        while low != high {
            let mid = index(low, offsetBy: distance(from: low, to: high)/2)
            if predicate(self[mid]) {
                low = index(after: mid)
            } else {
                high = mid
            }
        }
        return low
    }
}

Example usage:

(0 ..< 778).binarySearch { $0 < 145 } // 145