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








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


More information about the swift-evolution mailing list