With Swift, there’s almost always a better way to do things and when you get to that better way, it just rings with “of course”-ness.
As usual, this started as a question from a participant in #swift-dev. “This doesn’t work,” he said, and pasted the following.
func continueGame() { if self.gameLogic.count == 0 { return } self.gameLogic[0]() self.gameLogic.removeAtIndex(0) }
So I started kicking the wheels on it. To get going, I decided to use the following array of closures to test my approaches.
[Void -> Void] = [{println("one")}, {println("two")}, {println("three")}]
First, I explained about using a generator and the next() function:
var myarray : [Void -> Void] = [{println("one")}, {println("two")}, {println("three")}] var mygenerator = myarray.generate() if let closure = mygenerator.next() { closure() } if let closure = mygenerator.next() { closure() } if let closure = mygenerator.next() { closure() }
That wasn’t practical for a generalized implementation.So I built a few loops that eventually ended up like this:
while true { if let closure = mygenerator.next() { closure() } else { break } }
But Ken Ferry took one look at that, laughed, and suggested the following (far more elegant) solution instead:
while let closure = mygenerator.next() {closure()}
Beautiful and simple. Thanks, Ken.
2 Comments
Using a for in loop seems the swiftiest way to do this to me
var myarray : [Void -> Void] = [{println(“one”)}, {println(“two”)}, {println(“three”)}]
for closure in myarray {
closure()
}
no direct messing with a generator necessary
If the goal is to execute and remove all one by one, then another solution is:
var myarray : [Void -> Void] = [{println(“one”)}, {println(“two”)}, {println(“three”)}]
for _ in indices(myarray) { myarray.removeLast()() }