Make class iterable with for for for Loop?

I have a custom class:

class MyArrayClass {
...
}

      

This class is a custom list implementation.

I want to do the following:

var arr:MyArrayClass = MyArrayClass()
arr.append("first")
arr.append("second")
arr.append("third")

for entry in arr {
  println("entry: \(entry)")
}

      

Edit: the class I want to make iterable, JavaUtilArrayList, uses this IOSObjectArray class .

What protocol should my class validate so that it works in a for loop?

+3


source to share


2 answers


You can do it much faster using NSFastGenerator

:



extension MyArrayClass: SequenceType {
  public func generate() -> NSFastGenerator {
    return NSFastGenerator(self)
  }
}

      

0


source


You should take a look at this blog post on this exact topic. I'll write his summary here:

When you write:

// mySequence is a type that conforms to the SequenceType protocol.
for x in mySequence {
    // iterations here
}

      

Swift converts this value to:

var __g: Generator = mySequence.generate()
while let x = __g.next() {
    // iterations here
}

      

Therefore, in order to be able to enumerate your custom type, you need to force your class to implement the protocol SequenceType

. If you look at the SequenceType

protocol below, you can see that you only need to implement one method that returns an object corresponding to the protocol GeneratorType

( GeneratorType

included in the blog post).



protocol SequenceType : _Sequence_Type {
    typealias Generator : GeneratorType
    func generate() -> Generator
}

      

Here's an example of how to make it MyArrayClass

useful in a loop for

:

class MyArrayClass {
    var array: [String] = []

    func append(str: String) {
        array.append(str)
    }
}

extension MyArrayClass : SequenceType {
    // IndexingGenerator conforms to the GeneratorType protocol.
    func generate() -> IndexingGenerator<Array<String>> {
        // Because Array already conforms to SequenceType,
        // you can just return the Generator created by your array.
        return array.generate()
    }
}

      

Now, to put this into practice:

let arr = MyArrayClass()
arr.append("first")
arr.append("second")
arr.append("third")

for x in arr {
    println(x)
}

// Prints:
//     First
//     Second
//     Third

      

Hope that's the answer to your question.

+4


source







All Articles