Finding the first matching object in a collection, functionally

10 views
Skip to first unread message

Jens Alfke

unread,
May 21, 2015, 5:44:57 PM5/21/15
to swift-l...@googlegroups.com
A couple of times I’ve had the need to find the first (or just any) element of a collection that passes some test. Of course the traditional way to do this is to run a ‘for’ loop over the collection, test each element, and break when you find the match. But I wanted to do it functionally.

There doesn’t seem to be an existing operator for this. There’s a first( ) function but it just returns the first item in a collection. The closest thing I can find is to use filter( ) and then take the first element of the result, e.g.:
let bob = people.filter({$0.firstName == “bob”}).first
At first glance this looks inefficient — what if there are zillions of items that match the test? — but reading between the lines I’m guessing that filter may be lazy, generating items on demand, so stopping after the first one means the test would only succeed once. Is that true?

—Jens

Brent Royal-Gordon

unread,
May 21, 2015, 6:47:07 PM5/21/15
to Jens Alfke, swift-l...@googlegroups.com
Regular filter() is not lazy, but the Swift standard library supports lazy Sequences:

    lazy(people).filter { your test here }

Unfortunately, there's no way to first() the resulting Sequence, but that's easy to write:

    func first<Seq: SequenceType>(seq: Seq) -> Seq.Generator.Element? {
        var generator = seq.generate()
        return generator.next()
    }

HTH,
—Brent


--
You received this message because you are subscribed to the Google Groups "Swift Language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to swift-languag...@googlegroups.com.
To post to this group, send email to swift-l...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/swift-language/982ACBF2-1026-4575-9BC5-BE48021FDFC4%40mooseyard.com.
For more options, visit https://groups.google.com/d/optout.

Jens Alfke

unread,
May 21, 2015, 7:01:52 PM5/21/15
to Brent Royal-Gordon, swift-l...@googlegroups.com
Thanks! But if I’m going to write custom code to do this, I think I’d just rather write a function that iterates the collection and returns the first matching element, since it’s simpler and probably faster.

—Jens
Reply all
Reply to author
Forward
0 new messages