<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body><div>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<br></div>
<div>&nbsp;</div>
<div>for index in col.indices {<br></div>
<div>&nbsp; &nbsp; let elt = col[index]<br></div>
<div>&nbsp; &nbsp; // ...<br></div>
<div>}<br></div>
<div>&nbsp;</div>
<div>and that's pretty simple. But if I ever did need to map it, I'd just use the aforementioned zip() expression.<br></div>
<div>&nbsp;</div>
<div>-Kevin Ballard<br></div>
<div>&nbsp;</div>
<div>On Sun, Dec 27, 2015, at 12:08 AM, Patrick Pijnappel via swift-evolution wrote:<br></div>
<blockquote type="cite"><div dir="ltr"><div>-- Introduction<br></div>
<div>&nbsp;</div>
<div>There should be a property on CollectionType that returns a sequence of (Index, Element) tuples.<br></div>
<div>Currently&nbsp;<span class="font" style="font-family:monospace, monospace">enumerate()</span>&nbsp;is often used instead, but it is not well suited to the task and can lead to bugs.<br></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>-- Motivation<br></div>
<div>&nbsp;</div>
<div>Using&nbsp;<span class="font" style="font-family:monospace, monospace">enumerate()</span>&nbsp;instead of an <span class="font" style="font-family:monospace, ' monospace'">(Index, Element)</span> sequence has two main problems.<br></div>
<div>Both arise because&nbsp;<span class="font" style="font-family:monospace, monospace">enumerate()</span>&nbsp;returns a sequence of <span class="font" style="font-family:monospace, ' monospace'">(n, Element)</span> tuples,<br></div>
<div>where n is the element *number*, instead of a sequence of <span class="font" style="font-family:monospace, ' monospace'">(Index, Element)</span>.<br></div>
<div>&nbsp;</div>
<div>1) It doesn't work for collections&nbsp;not indexed by integers.<br></div>
<div>&nbsp;</div>
<div>2) It doesn't do what you might expect in some cases, as indices do not always start at 0.<br></div>
<div>For example <span class="font" style="font-family:monospace, ' monospace'">ArraySlice's</span>&nbsp;indices do not:&nbsp;<span class="font" style="font-family:monospace, ' monospace'">array[2..&lt;5]</span> starts with index 2.<br></div>
<div>Consider the following code to take the 2nd half of the array and remove all empty elements:<br></div>
<div>&nbsp;</div>
<div><span class="font" style="font-family:monospace, ' monospace'">var array = [ "", "a", "b", "c", "", "d" ]</span><br></div>
<div><span class="font" style="font-family:monospace, ' monospace'">var secondHalf = array[array.count/2..&lt;array.count]</span><br></div>
<div><span class="font" style="font-family:monospace, ' monospace'">for (index, element) in secondHalf.enumerate() {</span><br></div>
<div><span class="font" style="font-family:monospace, ' monospace'"><span style="white-space:pre;"></span>if element == "" {</span><br></div>
<div><span class="font" style="font-family:monospace, ' monospace'"><span style="white-space:pre;"></span>secondHalf.removeAtIndex(index)</span><br></div>
<div><span class="font" style="font-family:monospace, ' monospace'"><span style="white-space:pre;"></span>}</span><br></div>
<div><span class="font" style="font-family:monospace, ' monospace'">}</span><br></div>
<div>&nbsp;</div>
<div>This code will crash (ignoring for a moment this should probably be using filter).<br></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>-- Alternatives<br></div>
<div>&nbsp;</div>
<div>The same effect can already be achieved using the following:<br></div>
<div>&nbsp;</div>
<div><span class="font" style="font-family:monospace, ' monospace'">for index in collection.indices {</span><br></div>
<div><span class="font" style="font-family:monospace, ' monospace'">&nbsp; let element = collection[index]</span><br></div>
<div><span class="font" style="font-family:monospace, ' monospace'">&nbsp; // ...</span><br></div>
<div><span class="font" style="font-family:monospace, ' monospace'">}</span><br></div>
<div>&nbsp;</div>
<div>However having a dedicated <span class="font" style="font-family:monospace, ' monospace'">(Index, Element)</span> sequence has the following advantages:<br></div>
<div>a) It can help prevent people from using&nbsp;<span class="font" style="font-family:monospace, monospace">enumerate()</span>&nbsp;inappropriately.<br></div>
<div>b) It is very common use case that deserves shortening.<br></div>
<div>c) It can be chained (e.g. to map).<br></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>-- Proposed Solution<br></div>
<div>&nbsp;</div>
<div>Add a property/method on <span class="font" style="font-family:monospace, ' monospace'">CollectionType</span> that returns a sequence of <span class="font" style="font-family:monospace, ' monospace'">(Index, Element)</span> tuples.<br></div>
<div>For example, using a property named <span class="font" style="font-family:monospace, ' monospace'">indexed</span>:<br></div>
<div>&nbsp;</div>
<div><span class="font" style="font-family:monospace, ' monospace'">for (index, element) in collection.indexed {</span><br></div>
<div><span class="font" style="font-family:monospace, ' monospace'">&nbsp; // ...</span><br></div>
<div><span class="font" style="font-family:monospace, ' monospace'">}</span><br></div>
<div>&nbsp;</div>
<div>This should be the preferred idiom when you want both the index and the element.<br></div>
<div>&nbsp;</div>
<div>Note that <span class="font" style="font-family:monospace, ' monospace'">enumerate()</span> does still have valid roles to play:<br></div>
<div>- When you actually do want the element number, not the index.<br></div>
<div>- When you have a <span class="font" style="font-family:monospace, ' monospace'">SequenceType</span>, as it isn't indexed.<br></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>-- Implementation<br></div>
<div>&nbsp;</div>
<div>The feature could be entirely implemented using existing constructs:<br></div>
<div>&nbsp;</div>
<div><span class="font" style="font-family:monospace, ' monospace'">extension CollectionType {</span><br></div>
<div><span class="font" style="font-family:monospace, ' monospace'">&nbsp; var indexed: AnySequence&lt;(Index, Generator.Element)&gt; {</span><br></div>
<div><span class="font" style="font-family:monospace, ' monospace'">&nbsp; &nbsp; return AnySequence(indices.lazy.map { ($0, self[$0]) })</span><br></div>
<div><span class="font" style="font-family:monospace, ' monospace'">&nbsp; }</span><br></div>
<div><span class="font" style="font-family:monospace, ' monospace'">}</span><br></div>
<div>&nbsp;</div>
<div>Alternatively, a dedicated <span class="font" style="font-family:monospace, ' monospace'">SequenceType</span> and/or <span class="font" style="font-family:monospace, ' monospace'">GeneratorType</span> could be added.<br></div>
<div>&nbsp;</div>
</div>
<div><img style="height:1px !important;width:1px !important;border-top-width:0px !important;border-right-width:0px !important;border-bottom-width:0px !important;border-left-width:0px !important;margin-top:0px !important;margin-bottom:0px !important;margin-right:0px !important;margin-left:0px !important;padding-top:0px !important;padding-bottom:0px !important;padding-right:0px !important;padding-left:0px !important;" border="0" height="1" width="1" alt="" src="https://www.fastmailusercontent.com/proxy/981667c5fa75d2d6102189c7105ad9f6333023a0ad47163c7ff20e76523c1159/8647470737a3f2f25723030323431303e23647e23756e64676279646e2e65647f27766f2f60756e6f35707e6d3148765176786c673171614a7d2236454230345272776e43694d61464360346d4a727a7d2232443234316973476151574438767a54603e48717739376a58567554664f4a72367a44615c4a49454c6a40354663527463593450736531625351473833695b4377335f43657b473c65366e4f496a4468616935613875637057626d22324872535d2236455d4645414c417e676d43446755785945323468707b695a6a6b6777703b416c6f4a465969363a72463231534f657034707a54663135675144607d22364e673154766843667a63325259395256494036533a4a44394155476d23344d23344/open"><br></div>
<div><u>_______________________________________________</u><br></div>
<div>swift-evolution mailing list<br></div>
<div><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br></div>
<div><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br></div>
</blockquote><div>&nbsp;</div>
</body>
</html>