What you're asking for can already be done with `zip(col.indices, col)`. And in my experience the need for this sort of thing is rare enough that there's no need to have a dedicated property for it in the stdlib. The few times that I've needed this sort of thing, I've always just said
for index in col.indices { let elt = col[index] // ... } and that's pretty simple. But if I ever did need to map it, I'd just use the aforementioned zip() expression. -Kevin Ballard On Sun, Dec 27, 2015, at 12:08 AM, Patrick Pijnappel via swift-evolution wrote: > -- Introduction > > There should be a property on CollectionType that returns a sequence > of (Index, Element) tuples. Currently enumerate() is often used > instead, but it is not well suited to the task and can lead to bugs. > > > > -- Motivation > > Using enumerate() instead of an (Index, Element) sequence has two main > problems. Both arise because enumerate() returns a sequence of (n, > Element) tuples, where n is the element *number*, instead of a > sequence of (Index, Element). > > 1) It doesn't work for collections not indexed by integers. > > 2) It doesn't do what you might expect in some cases, as indices do > not always start at 0. For example ArraySlice's indices do not: > array[2..<5] starts with index 2. Consider the following code to > take the 2nd half of the array and remove all empty elements: > > var array = [ "", "a", "b", "c", "", "d" ] var secondHalf = > array[array.count/2..<array.count] for (index, element) in > secondHalf.enumerate() { if element == "" { > secondHalf.removeAtIndex(index) } } > > This code will crash (ignoring for a moment this should probably be > using filter). > > > > -- Alternatives > > The same effect can already be achieved using the following: > > for index in collection.indices { let element = collection[index] > // ... } > > However having a dedicated (Index, Element) sequence has the following > advantages: > a) It can help prevent people from using enumerate() inappropriately. > b) It is very common use case that deserves shortening. > c) It can be chained (e.g. to map). > > > > -- Proposed Solution > > Add a property/method on CollectionType that returns a sequence of > (Index, Element) tuples. For example, using a property named indexed: > > for (index, element) in collection.indexed { // ... } > > This should be the preferred idiom when you want both the index and > the element. > > Note that enumerate() does still have valid roles to play: > - When you actually do want the element number, not the index. > - When you have a SequenceType, as it isn't indexed. > > > > -- Implementation > > The feature could be entirely implemented using existing constructs: > > extension CollectionType { var indexed: AnySequence<(Index, > Generator.Element)> { return AnySequence(indices.lazy.map { ($0, > self[$0]) }) } } > > Alternatively, a dedicated SequenceType and/or GeneratorType could > be added. > > > _________________________________________________ > swift-evolution mailing list swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution