Reputation: 2520
I'm trying to remove items from an array inside a For loop. In order to do that, I follow the recommendation here to loop backwards like this:
for (index, bullet:Bullet) in stride(from: bullets!.count - 1, through: 0, by: -1) {
if(currentTime - bullet.life! > bullet.maxLife){
bullet.removeFromParent()
bullets?.removeAtIndex(index)
}
}
But I'm getting an error
Type '($T12, Bullet)' does not conform to protocol 'Strideable'
UPDATE
Here is the class for the bullet. This is a Cocos2D app, hence the CCDrawNode Type.
import Foundation
class Bullet: CCDrawNode {
var speed:CGPoint?
var maxSpeed:CGFloat?
var angle:CGFloat?
var life:CGFloat?
var maxLife:CGFloat = 0.5
init(angle: CGFloat){
super.init()
self.drawDot(ccp(0,0), radius: 2, color: CCColor.whiteColor());
self.contentSize = CGSize(width: 4, height: 4)
self.angle = angle
maxSpeed = 10
speed = CGPoint(x: maxSpeed! * CGFloat(sin(angle)), y: maxSpeed! * CGFloat(cos(angle)))
}
override func update(delta: CCTime) {
self.position.x += speed!.x
self.position.y += speed!.y
}
}
Upvotes: 2
Views: 4676
Reputation:
Here's a definition of the protocol: Stridable
You can implement it like this:
final class Foo: Strideable {
var value: Int = 0
init(_ newValue: Int) { value = newValue }
func distanceTo(other: Foo) -> Int { return other.value - value }
func advancedBy(n: Int) -> Self { return self.dynamicType(value + n) }
}
func ==(x: Foo, y: Foo) -> Bool { return x.value == y.value }
func <(x: Foo, y: Foo) -> Bool { return x.value < y.value }
let a = Foo(10)
let b = Foo(20)
for c in stride(from: a, to: b, by: 1) {
println(c.value)
}
You need to provide the functions distanceTo
, advancedBy
and the operators ==
and <
. There is more information about these functions in the documentation I linked.
Upvotes: 5
Reputation: 539975
Alternative solution using the filter()
method, avoiding the need for an index
altogether:
bullets!.filter { bullet -> Bool in
if (currentTime - bullet.life! > bullet.maxLife) {
bullet.removeFromParent()
return false // remove from array
} else {
return true // keep in array
}
}
Upvotes: 4
Reputation: 72770
You should change your loop as follows:
for index in stride(from: bullets!.count - 1, through: 0, by: -1) {
let bullet = bullets![index]
by moving the bullet
assignment to a separate statement inside the loop.
Upvotes: 0