<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div><span></span></div><div><span>You could replace `forEach` with a supped up `map` that also allowed `break` and `continue`. The following </span><font class="" style="background-color: rgba(255, 255, 255, 0);">library function gives `continue` and `break` and also combines `repeat`, `times`, `forEach`, `filter`, `flatMap`, and `map` into one:</font><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);"><br class=""></font><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class="">public</span> <span class="">final</span> <span class="">class</span> MapController<E, R> {</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">var</span> results = [R]()</span></div><p class="" style="margin: 0px; line-height: normal; min-height: 13px;"><span style="background-color: rgba(255, 255, 255, 0);"> </span></p><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">var</span> isContinuing = <span class="">true</span></span></div><p class="" style="margin: 0px; line-height: normal; min-height: 13px;"><span style="background-color: rgba(255, 255, 255, 0);"> </span></p><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">init</span><C: CollectionType <span class="">where</span> C.Generator.Element == E>(<span class="">_</span> collection: C, sizeEstimate: Int = <span class="">0</span>, <span class="">@noescape</span> mapper: (controller: MapController<E, R>, element: E) <span class="">throws</span> -> R?) <span class="">rethrows</span> {</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> results.reserveCapacity(sizeEstimate)</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">for</span> <span class="">var</span> generator = collection.generate(), element = generator.next(); element != <span class="">nil</span> && isContinuing; element = generator.next() {</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">let</span> result = <span class="">try</span> mapper(controller: <span class="">self</span>, element: element!)</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">if</span> <span class="">let</span> actualResult = result {</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> results.append(actualResult)</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> }</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> }</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> }</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">}</span></div><div class="" style="margin: 0px; line-height: normal; min-height: 13px;"><span style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class="">extension</span><span class=""> </span>CollectionType<span class=""> {</span></span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class=""> </span>/// Controllable `map`, additional controls beyond simple `map` are:</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">///</span></span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class=""> </span>/// 1. Continue without returning a result (`return nil`)</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class=""> </span>/// 2. Return multiple results (`control.results += [...]` then `return nil`)</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class=""> </span>/// 3. Break (`control.isContinuing = false` then `return nil`)</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">///</span></span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class=""> </span>/// These additional controls allow this `map` to function like `repeat`, `times`, `forEach`, `filter`, `flatMap`, and `map` combined into one as well as providing an early termination (break).</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">@warn_unused_result</span> <span class="">func</span> map<R>(sizeEstimate sizeEstimate: Int = <span class="">0</span>, <span class="">@noescape</span> mapper: (controller: MapController<<span class="">Self</span>.Generator.Element, R>, element: <span class="">Self</span>.Generator.Element) <span class="">throws</span> -> R?) <span class="">rethrows</span> -> [<span class="">R</span>] {</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">return</span> <span class="">try</span> MapController(<span class="">self</span>, sizeEstimate: sizeEstimate, mapper: mapper).results</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> }</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">}</span></div><div class="" style="margin: 0px; line-height: normal; min-height: 13px;"><span style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">// Demonstration of full functionality including continue, break, and multiple returns</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class="">var</span> result = (<span class="">0</span> ..< <span class="">5</span>).map { (control, index) -> <span class="">Int</span>? <span class="">in</span></span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">switch</span> index {</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">case</span> <span class="">1</span>:</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class=""> </span><span class="">return</span><span class=""> </span><span class="">nil</span><span class=""> </span>// Continue - skip 1 (`filter`)</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">case</span> <span class="">2</span>:</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class=""> control.results.append(</span><span class="">2</span><span class="">) </span>// Yield two results - this one and the 'return’ yield (`flatMap`)</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">case</span> <span class="">3</span>:</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class=""> control.isContinuing = </span><span class="">false</span><span class=""> </span>// Break after next yield - which could be `return nil` if there are no more results</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class=""> </span>default<span class="">:</span></span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">break</span></span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> }</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class=""> </span><span class="">return</span><span class=""> index </span>// Yield next result - except for case 1 all the above yield `index`</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">}</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class="">print(result) </span>// prints `[0, 2, 2, 3]` note missing "1", double "2", and last is "3"</span></div><div class="" style="margin: 0px; line-height: normal; min-height: 13px;"><span style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">// Demonstration of `repeat`/`forEach`/`times` like usage - note `(_, _) -> Void?`</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">result = [Int]()</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">(<span class="">0</span> ..< <span class="">3</span>).map { (<span class="">_</span>, <span class="">_</span>) -> <span class="">Void</span>? <span class="">in</span></span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> result.append(<span class="">1</span>) <span class="">// Do whatever - in this case append to a global</span></span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class=""> </span><span class="">return</span><span class=""> </span><span class="">nil</span><span class=""> </span>// Don't yield any results</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">}</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class="">print(result) </span>// prints `[1, 1, 1]`</span></div></blockquote><font class="" style="background-color: rgba(255, 255, 255, 0);"><br class=""></font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">Would this be a superior alternative to both `forEach` and `times` in the library and `repeat` as a language feature?</font></div><span></span><br><span>Sent from my iPad</span></div></body></html>