<div dir="ltr"><div>-- Introduction</div><div><br></div><div>There should be a property on CollectionType that returns a sequence of (Index, Element) tuples.</div><div>Currently <span style="font-family:monospace,monospace">enumerate()</span> is often used instead, but it is not well suited to the task and can lead to bugs.</div><div><br></div><div><br></div><div><br></div><div>-- Motivation</div><div><br></div><div>Using <span style="font-family:monospace,monospace">enumerate()</span> instead of an <font face="monospace, monospace">(Index, Element)</font> sequence has two main problems.</div><div>Both arise because <span style="font-family:monospace,monospace">enumerate()</span> returns a sequence of <font face="monospace, monospace">(n, Element)</font> tuples,</div><div>where n is the element *number*, instead of a sequence of <font face="monospace, monospace">(Index, Element)</font>.</div><div><br></div><div>1) It doesn&#39;t work for collections not indexed by integers.</div><div><br></div><div>2) It doesn&#39;t do what you might expect in some cases, as indices do not always start at 0.</div><div>For example <font face="monospace, monospace">ArraySlice&#39;s</font> indices do not: <font face="monospace, monospace">array[2..&lt;5]</font> starts with index 2.</div><div>Consider the following code to take the 2nd half of the array and remove all empty elements:</div><div><br></div><div><font face="monospace, monospace">var array = [ &quot;&quot;, &quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;&quot;, &quot;d&quot; ]</font></div><div><font face="monospace, monospace">var secondHalf = array[array.count/2..&lt;array.count]</font></div><div><font face="monospace, monospace">for (index, element) in secondHalf.enumerate() {</font></div><div><font face="monospace, monospace"><span style="white-space:pre">  </span>if element == &quot;&quot; {</font></div><div><font face="monospace, monospace"><span style="white-space:pre">    </span>secondHalf.removeAtIndex(index)</font></div><div><font face="monospace, monospace"><span style="white-space:pre">  </span>}</font></div><div><font face="monospace, monospace">}</font></div><div><br></div><div>This code will crash (ignoring for a moment this should probably be using filter).</div><div><br></div><div><br></div><div><br></div><div>-- Alternatives</div><div><br></div><div>The same effect can already be achieved using the following:</div><div><br></div><div><font face="monospace, monospace">for index in collection.indices {</font></div><div><font face="monospace, monospace">  let element = collection[index]</font></div><div><font face="monospace, monospace">  // ...</font></div><div><font face="monospace, monospace">}</font></div><div><br></div><div>However having a dedicated <font face="monospace, monospace">(Index, Element)</font> sequence has the following advantages:</div><div>a) It can help prevent people from using <span style="font-family:monospace,monospace">enumerate()</span> inappropriately.</div><div>b) It is very common use case that deserves shortening.</div><div>c) It can be chained (e.g. to map).</div><div><br></div><div><br></div><div><br></div><div>-- Proposed Solution</div><div><br></div><div>Add a property/method on <font face="monospace, monospace">CollectionType</font> that returns a sequence of <font face="monospace, monospace">(Index, Element)</font> tuples.</div><div>For example, using a property named <font face="monospace, monospace">indexed</font>:</div><div><br></div><div><font face="monospace, monospace">for (index, element) in collection.indexed {</font></div><div><font face="monospace, monospace">  // ...</font></div><div><font face="monospace, monospace">}</font></div><div><br></div><div>This should be the preferred idiom when you want both the index and the element.</div><div><br></div><div>Note that <font face="monospace, monospace">enumerate()</font> does still have valid roles to play:</div><div>- When you actually do want the element number, not the index.</div><div>- When you have a <font face="monospace, monospace">SequenceType</font>, as it isn&#39;t indexed.</div><div><br></div><div><br></div><div><br></div><div>-- Implementation</div><div><br></div><div>The feature could be entirely implemented using existing constructs:</div><div><br></div><div><font face="monospace, monospace">extension CollectionType {</font></div><div><font face="monospace, monospace">  var indexed: AnySequence&lt;(Index, Generator.Element)&gt; {</font></div><div><font face="monospace, monospace">    return AnySequence(indices.lazy.map { ($0, self[$0]) })</font></div><div><font face="monospace, monospace">  }</font></div><div><font face="monospace, monospace">}</font></div><div><br></div><div>Alternatively, a dedicated <font face="monospace, monospace">SequenceType</font> and/or <font face="monospace, monospace">GeneratorType</font> could be added.</div><div><br></div></div>