# [swift-evolution] Multi dimensional - iterator, Iterator2D, Iterator3D

Ted F.A. van Gaalen tedvgiosdev at gmail.com
Sat Jul 30 15:48:28 CDT 2016

```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")
///  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)
} )
}

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160730/dea0152f/attachment.html>
```