[swift-evolution] Proposal: Add function SequenceType.find()
Donnacha Oisín Kidney
oisin.kidney at gmail.com
Wed Dec 30 09:33:27 CST 2015
+1 on this.
I see a lot of code like this:
sequence.filter(predicate).first
Which is of course is inefficient. However, the go-to optimisation:
sequence.lazy.filter(predicate).first
Is not necessarily better, and has some strange behaviour:
let array = [1, 2, 3, 4, 5, 6]
func noisyPredicate(n: Int) -> Bool {
print(n, terminator: " ")
return n > 2
}
array.lazy.filter(noisyPredicate).first
// 1 2 3 1 2 3
AnySequence(array).lazy.filter(noisyPredicate).first
// 1 2 3 4 5 6
If it’s called on a collection, the collection is only evaluated up until the element being looked for, but it’s done twice. If it’s called on a sequence, the whole sequence is evaluated, regardless of where the element is found.
I think that find is maybe not the best name, though. It’s not immediately clear that it doesn’t return an index. I’d prefer to call it first, as in:
extension SequenceType {
/// Returns the first element where `predicate` returns `true`, or `nil`
/// if such value is not found.
public func first(@noescape thatSatisfies: (Self.Generator.Element) throws -> Bool) rethrows -> Self.Generator.Element? {
for elt in self {
if try thatSatisfies(elt) {
return elt
}
}
return nil
}
}
[1, 2, 3, 4, 5].first(thatSatisfies: (Int) throws -> Bool)
[1, 2, 3, 4, 5].first { $0 > 3 }
> On 30 Dec 2015, at 10:13, James Campbell via swift-evolution <swift-evolution at swift.org> wrote:
>
> We should add the full collection of ruby methods http://matthewcarriere.com/06/23/using-select-reject-collect-inject-and-detect/ <http://matthewcarriere.com/06/23/using-select-reject-collect-inject-and-detect/>
>
>
>
> Sent from my iPhone
>
> On 30 Dec 2015, at 02:40, Keith Smiley via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>
>> +1. We've added an extension for this and find it very useful.
>> On Tue, Dec 29, 2015 at 18:38 Kevin Ballard via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> I'm proposing a new extension method on SequenceType called find(). It's similar to CollectionType.indexOf() except it returns the element:
>>
>> extension SequenceType {
>> /// Returns the first element where `predicate` returns `true`, or `nil`
>> /// if such value is not found.
>> public func find(@noescape predicate: (Self.Generator.Element) throws -> Bool) rethrows -> Self.Generator.Element? {
>> for elt in self {
>> if try predicate(elt) {
>> return elt
>> }
>> }
>> return nil
>> }
>> }
>>
>> -Kevin Ballard
>>
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151230/d3b26c10/attachment.html>
More information about the swift-evolution
mailing list