<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On 19 Jun 2016, at 05:58, Saagar Jha via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><p class="">This isn’t actually that complex, especially if you ditch the “C-style” for loop algorithm and switch it to, as you mentioned, “filtering code”. <code class="">filter</code>, <code class="">enumerated</code> (to get indices), and <code class="">map</code> (to go back to elements) are more than up to the task. Plus, this is much more efficient.</p>
<pre class=""><code class="">var myArray = [0, 1, 2]
let indices: Set = [0, 1]
myArray = myArray.enumerated().filter {
    return !indices.contains($0.offset)
}.map {
    return $0.element // to get the elements back
}
print(myArray) // prints “[2]"
</code></pre><p class="">Adding it to the standard library might be useful, but it’s not as hard as it looks.</p></div></div></blockquote></div><div class="">Has .enumerated() been changed to use the collection’s internal Index type? Last time I tried something like this it failed because .enumerated() only returns numeric offsets, but the index type of a collection may not necessary be compatible (not all indices are just a plain numeric value, consider a type that returns AnyIndex). So this will only work when your indices are integers starting from zero.</div><div class=""><br class=""></div><div class="">I think the following should work for the generic case, and is pretty similar:</div><div class=""><br class=""></div><blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">extension MutableCollection {</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>public mutating func remove(indices: Set&lt;Index&gt;) {</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space: pre;">                </span>var index = self.startIndex</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space: pre;">                </span>self = self.filter {</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space: pre;">                        </span>let result = indices.contains(index)</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space: pre;">                        </span>self.formIndex(after: &amp;index)</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space: pre;">                        </span>return result</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space: pre;">                </span>}</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>}</font></div><div class=""><font face="Monaco" class="">}</font></div></blockquote><div class=""><br class=""></div><div class=""><div class="">(note: I'm not in a position to test this just now so it may not work exactly as written, but that’s the gist of how to do it safely I think)</div></div><div class=""><br class=""></div><div class="">The main question I have is how do you get into a situation where you’ve generated the indices, but could not put the same code into a call to .filter? For example:</div><div class=""><br class=""></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>var indicesToRemove:Set&lt;Index&gt; = []</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>for eachIndex in myArray.indices {</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>if someCondition(myArray[eachIndex]) { indicesToRemove.insert(eachIndex) }</font></div><div class=""><span style="font-family: Monaco;" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</span></div><div class=""><span style="font-family: Monaco;" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>myArray.remove(indices: indicesToRemove)</span></div><div class=""><br class=""></div><div class="">Could be rewritten as:</div><div class=""><br class=""></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>myArray = myArray.filter { someCondition($0) }</font></div><div class=""><br class=""></div><div class="">If what we want is in-place removal then I think what we need is some kind of MutatingIteratorProtocol which includes a .remove() method; this method would remove the last element retrieved without invalidating the iterator or skipping an element, allowing us to do the following:</div><div class=""><br class=""></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>var iterator =&nbsp;myArray.makeIterator() // Conforms to MutatingIteratorProtocol</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>while let eachElement = iterator.next() {</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>if someCondition(eachElement) { iterator.remove() }</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</font></div></body></html>