[swift-evolution] [Proposal draft] Introducing `indexed()` collections
Dave Abrahams
dabrahams at apple.com
Fri Sep 30 22:53:32 CDT 2016
on Wed Sep 28 2016, Erica Sadun <swift-evolution at swift.org> wrote:
> Indices have a specific, fixed meaning in Swift, which are used to create valid collection
> subscripts. This proposal introduces indexed() to produce a more semantically relevant sequence by
> pairing a collection's indices with its members. While it is trivial to create a solution in Swift,
> the most common developer approach shown here calculates indexes twice:
>
> extension Collection {
> /// Returns a sequence of pairs (*idx*, *x*), where *idx* represents a
> /// consecutive collection index, and *x* represents an element of
> /// the sequence.
> func indexed() -> Zip2Sequence<Self.Indices, Self> {
> return zip(indices, self)
> }
> }
How does this calculate indices twice?
> Incrementing an index in some collections can be unnecessarily
> costly.
Seems like it's only *unnecessarily* costly in badly implemented
collections?
> In a lazy filtered collection, an index increment is potentially
> O(N). We feel this is better addressed introducing a new function into
> the Standard Library to provide a more efficient design that avoids
> the attractive nuisance of the "obvious" solution.
I am generally opposed to adding this. The usual solution developers
will reach for here is:
for i in x.indices {
somethingWith(x[i])
}
zip(indices, self) is only suboptimal for lazy filtered sequences, which
should be used with care anyhow (see the note here:
http://swiftdoc.org/v3.0/type/LazyFilterCollection/).
If you really need a lazy sequence of pairs that's optimal with lazy
filtered sequences,
x.indices.lazy.map { ($0, x[$0]) }
is a good solution and pretty easy to write.
--
-Dave
More information about the swift-evolution
mailing list