[swift-evolution] (Draft) Add last(where:) and lastIndex(where:) methods

Dave Abrahams dabrahams at apple.com
Thu May 19 16:58:26 CDT 2016


on Tue May 10 2016, Nate Cook <swift-evolution at swift.org> wrote:

> I've needed these in the past and used them in other languages—any feedback on this  idea?
>
> ---------------------------------------------------------------------------------------------------------------------
>
> Add last(where:) and lastIndex(where:) Methods to Bidirectional Collections
>
> The standard library should include methods for finding the last element of a bidirectional collection that matches a
> predicate, along with the index of that element.

Why shouldn't this work with all Collections, with an optimized version
for BidirectionalCollections?

> Motivation
>
> The standard library currently has (or will soon have) methods that perform a linear search from the beginning of a
> collection to find an element that matches a predicate:
>
> let a = [20, 30, 10, 40, 20, 30, 10, 40, 20]
> a.first(where: { $0 > 25 })         // 30
> a.index(of: 10)                     // 2
> a.index(where: { $0 > 25 })         // 1

> Unfortunately, there is no such method that searches from the end of a bidirectional collection. Finding the last of
> particular kind of element has multiple applications, particularly with text, such as wrapping a long string into
> lines of a maximum length or trimming whitespace from the beginning and end of a string.
>
> This limitation can be worked around by using the methods above on the reversed collection, but the resulting code is
> truly dreadful. For example, to find the corresponding last index to a.index(where: { $0 > 25 }), this unholy
> incantation is required:
>
> (a.reversed().index(where: { $0 > 25 })?.base).flatMap({ a.index(before: $0) })
>
> Wat.
>
> Proposed solution
>
> Bidirectional collections should include three new methods for symmetry with the existing forward-searching
> APIs: last(where:), lastIndex(where:), and lastIndex(of:), specifically for collections of Equatable elements.
>
> These additions would remove the need for searching in a reversed collection and allow code like the following:
>
> a.last(where: { $0 > 25 })          // 40
> a.lastIndex(of: 10)                 // 6
> a.lastIndex(where: { $0 > 25 })     // 7

I think we need to consider consistency of naming more carefully in this
area.  If we go this route, I want:

  x.firstIndex(of: 10)

-- 
-Dave



More information about the swift-evolution mailing list