-- 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