With your method, don't you need to write a new method for every dimension? On Mon, Aug 1, 2016 at 08:43 Ted F.A. van Gaalen via swift-users < swift-users@swift.org> wrote:
> Hi Erica > > That would also be a workable solution, but imho still too tedious as > it has been so for many years, with nested iteration statements… > many times this is for;; for;; for tables and for;;for;;for;; for 3D > structuring. > > > Swift offers nice features (like protocols and generics as you know) to > improve this. > > - I no longer have to nest for;; s so, Now I rather do this: > Your example can already be coded like this: > > iterate2D( 1, 2, { $0 < 64 } , > 1, 2, { $0 < 64 } , > {outerIndex,innerIndex in > print (outerIndex,InnerIndex) > > return true // Obligatory. return “false" to break > } ) > > With no chances in Swift, this already works like a charm! > Imho much more readable and compact, > > Uses - AFAICS from a programmers’s perspective - no > underlying deep collection based coding with Sequence. etc. > > I am already deploying it in my own apps e.g. l > (replaced for;; for;; for;; in the app) > > By using this new iterator…() functions my coding gets leaner > and errors are easier to spot. > > Actual working code with Swift 2.x here: > > func generateTiles() > { > let w: Float = 20 // tile size > let h: Float = 5 > let l: Float = 5 > > > let xstart: Float = -120 > let ystart: Float = -60 > let zstart: Float = -10 > > > let xend: Float = 120 > let yend: Float = 60 > let zend: Float = 10 > > > let tolerance:Float = 0.001 // float drift compensation > > > iterate3D( xstart, w * 1.2, { $0 < xend + tolerance } , > ystart, h * 1.2, { $0 < yend + tolerance } , > zstart, l * 1.2, { $0 < zend + tolerance } , > { > x,y,z in > self.addTile(x,y,z, > w,h,l) > return true > } ) > } > > This generates a group of blocks or tiles in my Apple TV app (under > construction) > like the one you can see in the image “Cloinckz” on my website > www.tedvg.com. > > I also prefer the one dimensional iterate(.. too above the for;; or > stride() > > One could extend these iterator…() functions by adding closures for pre > and post iteration handling, > like for printing headers and footers before and/or after a complete > [inner] iteration. > > Note that breaking with *return false* -which is equivalent to the “break” > stmt in > a classical for;; - does not only leave a nested iteration, but also the > outer ones. > (maybe a TODO to make individual level- break possible) As it is now, If > one > wants to break at the deep iteration level, then one should nest this > using 1D iterators. > > > Anyway, this is just a thought starting to think about multi-dimensional > iterators, > and other (encapsulation?) of multi dimensional data as well. > In any case for 2D because table data is used very frequently in many > apps. as > most data are in tables. > > You won’t believe this :o) but in a sense I might not make so much fuzz > anymore > to keep the for;; as this proves to me that I can solve things much > better that I thought. > So, I have to rethink this. > > Kind Regards > Ted > www.ravelnotes.com > > > > > > > > On 31.07.2016, at 18:33, Erica Sadun <er...@ericasadun.com> wrote: > > I'm replying on Swift-Users and bcc'ing in Swift-Evolution to comply with > the core team's request to focus SE on the current mission statement. > > At some point soon, Russ Bishop's PR > https://github.com/apple/swift/pull/3600 will be incorporated into Swift > 3. This PR adds `prefix(while:)` and `drop(while:)` to finish implementing > SE-0045. Once that's done, you can combine `sequence(first:, next:)` and > `prefix(while:)` to into a single function `sequence(first:, next:, > while:)` like this: > > public func sequence<T>(first: T, next: (T) -> T?, while test: (T) -> > Bool) -> UnfoldSequence<T, UnfoldSequence<T, (T?, Bool)>> { > return sequence(first: first, next: next).prefix(while: test) > } > > The combined sequence/prefix call allows you to create loops like this: > > for outerIndex in sequence(first: 1, next: { $0 * 2 }, while: { $0 <= 64 > }) { > for innerIndex in sequence(first: 1, next: { $0 * 2 }, while: { $0 <= > 64 }) { > print(outerIndex, innerIndex) > } > } > > These loops can be nested. break and continue work. You can use tuples > for multiple arguments. While I'd like to see a combined form adopted into > Swift 4b (the deferred "sugar"), it isn't a high priority. > > -- E > > > On Jul 31, 2016, at 7:18 AM, Ted F.A. van Gaalen via swift-evolution < > swift-evolut...@swift.org> wrote: > > > On 31.07.2016, at 04:28, jaden.gel...@gmail.com wrote: > > What benefit do Iterator2D and Iterator3D provide that nesting does not? > > Hi Jaden, > well, simply because of hiding/enclosing repetitive functionality > like with every other programming element is convenient, > prevents errors and from writing the same over and over again. > That is why there are functions. > but you already know that, of course. > Kind Regards > TedvG > > > On Jul 30, 2016, at 1:48 PM, Ted F.A. van Gaalen via swift-evolution < > swift-evolut...@swift.org> wrote: > > Hi Chris, > > thanks for the tip about Hirundo app! > > A positive side-effect of removing the classical for;; loop > (yes, it’s me saying this :o) is that it forces me to find > a good and generic equivalent for it, > making the conversion of my for;;s to 3.0 easier. > which is *not* based on collections or sequences and > does not rely on deeper calls to Sequence etc. > > so, I’ve made the functions [iterator, iterator2D, iterator3D] (hereunder) > wich btw clearly demonstrate the power and flexibility of Swift. > > Very straightforward, and efficient (i assume) just like the classical > for;; loop. > It works quite well in my sources. > > As a spin-off, I’ve extended these to iterators for matrices 2D and > cubes? 3D... > > Question: > Perhaps implementing “multi dimensional iterator functions > in Swift might be a good idea. so that is no longer necessary to > nest/nest/nest iterators. > > Met vriendelijke groeten, sorry for my “intensity” in discussing the > classical for;; > I'll have to rethink this for;; again.. > Thanks, Ted. > > Any remarks ( all ), suggestions about the code hereunder: ? > > protocol NumericType > { > func +(lhs: Self, rhs: Self) -> Self > func -(lhs: Self, rhs: Self) -> Self > func *(lhs: Self, rhs: Self) -> Self > func /(lhs: Self, rhs: Self) -> Self > func %(lhs: Self, rhs: Self) -> Self > } > > extension Double : NumericType { } > extension Float : NumericType { } > extension CGFloat: NumericType { } > extension Int : NumericType { } > extension Int8 : NumericType { } > extension Int16 : NumericType { } > extension Int32 : NumericType { } > extension Int64 : NumericType { } > extension UInt : NumericType { } > extension UInt8 : NumericType { } > extension UInt16 : NumericType { } > extension UInt32 : NumericType { } > extension UInt64 : NumericType { } > > > /// Simple iterator with generic parameters, with just a few lines of code. > /// for most numeric types (see above) > /// Usage Example: > /// > /// iterate(xmax, { $0 > xmin}, -xstep, > /// {x in > /// print("x = \(x)") > /// return true // returning false acts like a break > /// } ) > /// > /// -Parameter vstart: Initial value > /// -Parameter step: The iteration stepping value. > /// -Parameter test: A block with iteration test. e.g. {$0 > 10} > /// > /// -Parameter block: A block to be executed with each step. > /// The block must include a return true (acts like "continue") > /// or false (acts like "break") > /// -Please Note: > /// There is minor precision loss ca: 1/1000 ... 1/500 > /// when iterating with floating point numbers. > /// However, in most cases this can be safely ignored. > /// made by ted van gaalen. > > > func iterate<T:NumericType> ( > vstart: T, > _ vstep: T, > _ test: (T) -> Bool, > _ block: (T) -> Bool ) > { > var current = vstart > > while test(current) && block(current) > { > current = current + vstep > } > } > > > /// X,Y 2D matrix (table) iterator with generic parameters > func iterate2D<T:NumericType> ( > xstart: T, _ xstep: T, _ xtest: (T) -> Bool, > _ ystart: T, _ ystep: T, _ ytest: (T) -> Bool, > _ block: (T,T) -> Bool ) > { > var xcurrent = xstart > var ycurrent = ystart > > var dontStop = true > > while xtest(xcurrent) && dontStop > { > ycurrent = ystart > while ytest(ycurrent) && dontStop > { > dontStop = block(xcurrent, ycurrent) > ycurrent = ycurrent + ystep > } > xcurrent = xcurrent + xstep > } > } > > > /// X,Y,Z 3D (cubic) iterator with generic parameters: > > func iterate3D<T:NumericType> ( > xstart: T, _ xstep: T, _ xtest: (T) -> Bool, > _ ystart: T, _ ystep: T, _ ytest: (T) -> Bool, > _ zstart: T, _ zstep: T, _ ztest: (T) -> Bool, > _ block: (T,T,T) -> Bool ) > { > var xcurrent = xstart > var ycurrent = ystart > var zcurrent = zstart > > var dontStop = true > > while xtest(xcurrent) && dontStop > { > ycurrent = ystart > while ytest(ycurrent) && dontStop > { > zcurrent = zstart > while ztest(zcurrent) && dontStop > { > dontStop = block(xcurrent, ycurrent, zcurrent) > zcurrent = zcurrent + zstep > } > ycurrent = ycurrent + ystep > } > xcurrent = xcurrent + xstep > } > } > > > func testIterator() > { > iterate(0.0, 0.5, {$0 < 1000.00000} , > { value in > print("Value = \(value) ") > return true > } ) > > let startv: CGFloat = -20.0 > let stepv: CGFloat = 0.5 > > iterate(startv, stepv, {$0 < 1000.00000} , > { val in > print("R = \(val)") > return true > } ) > > let tolerance = 0.01 // boundary tolerance for floating point type > > iterate2D( 0.0, 10.0, { $0 < 100.0 + tolerance } , > 0.0, 5.0, { $0 < 50.0 + tolerance } , > {x,y in > print("x = \(x) y = \(y)") > return true // false from block stops iterating ( like > break) > } ) > > iterate3D( 0.0, 10.0, { $0 < 30.0 } , // x > 0.0, 5.0, { $0 < 20.0 } , // y > 10.0, -5.0, { $0 > -10.0 } , // z > {x,y,z in > print("x = \(x) y = \(y) z = \(z)") > if z < 0.0 > { > print ( "** z value \(z) is below zero! **" ) > > return false // (acts as break in for;;) > } > return true // return stmt is obligatory (continue) > } ) > } > > > > > > > > > _______________________________________________ > swift-evolution mailing list > swift-evolut...@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution > > > _______________________________________________ > swift-evolution mailing list > swift-evolut...@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution > > > > _______________________________________________ > swift-users mailing list > swift-users@swift.org > https://lists.swift.org/mailman/listinfo/swift-users >
_______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users