As already mentioned, reduce specifically designed to evaluate the entire sequence and, therefore, is not intended for short circuiting. Using it this way to find the index of an element that matches a given predicate is best done with indexOf , as @Casey says .
Also, as in Swift 3, Sequence now has a first(where:) function that allows you to find the first element that satisfies a given predicate. This might be an even more suitable alternative than indexOf , as it returns an element instead of an index (although in your particular example they are the same).
You can write your example as follows:
func firstAbove100(_ a:[Int]) -> Int? { guard a.count > 1 else {return nil} return (0..<a.count-1).first { i in a[i]+a[i+1] > 100 } }
However, if you need a more general high-level function that will iterate over a sequence and exit it, if it finds a non-zero result of a given predicate, you can always write your own find function:
extension SequenceType { func find<T>(@noescape predicate: (Self.Generator.Element) throws -> T?) rethrows -> T? { for element in self { if let c = try predicate(element) {return c} } return nil } }
Now you can write your firstAbove100 function as follows:
func firstAbove100(a:[Int]) -> Int? { if a.count < 2 { return nil } return (0..<a.count-1).find { i in a[i]+a[i+1] > 100 ? i : nil } }
and now it will close when it finds a pair of elements that add above 100.
Or say, instead of returning the index of the first pair of elements in your array that add more than 100, now you want to return the sum of the elements. Now you can write it as follows:
func sumOfFirstAbove100(a:[Int]) -> Int? { guard a.count > 1 else {return nil} return (0..<a.count-1).find { i in let sum = a[i]+a[i+1] return sum > 100 ? sum : nil } }
let a = [10, 20, 30, 40, 50, 60, 70, 80, 90] print(sumOfFirstAbove100(a)) // prints: Optional(110)
The find function iterates through the array, applying a predicate to each element (in this case, the indices of your array). If the predicate returns nil , it will continue to iterate. If the predicate returns non-nil, it will return this result and stop the iteration.