I want to iterate through all values in an enum but given certain conditions I want to give up and move to the next value. Any attempt at a break
or continue
statement and the compiler says that '.allCases.forEach' is not a loop as in 'func test1'.
The best workaround I've come up with is func test2
but it seems "non-swifty" and I could just have a bunch of nested if
blocks that seem extra. So what is .allCases.forEach
if not a loop and more importantly, is there a different/better way to iterate through the enum
?
Updated: added func 'processFoolPower' with solution 1 as a small example of the goal. Think large chess board.
enum directions: Int, CaseIterable {
case up = 0, upRight, right, downRight, down, downLeft, left, upLeft, invalid
}
func test1() {
print("forEach: ")
moveDirections.allCases.forEach {
if $0 == .up { () } // I want to { continue } here to next direction
if $0.rawValue == 4 { () } // or { continue } here to next direction
testPrint(test: $0)
}
}
func test2() {
print("for : ")
for direction in 0..<moveDirections.allCases.count {
if moveDirections(rawValue: direction) == .up { continue }
if direction == 4 { continue }
testPrint(test: moveDirections(rawValue: direction).self!)
}
}
func testPrint(test: moveDirections) {
print(test.self)
}
mutating func processFoolPower(foolPiece: gamePiece, owner: Bool) {
var testPiece: gamePiece = MockData.blankPiece
for direction in moveDirections.allCases {
let testSquare = foolPiece.location! + SquareShift(direction)
if testSquare < 0 || testSquare > 143 { continue } // test for off top/bottom of board
switch direction {
case .down, .up, .left, .right:
if isStraight(from: foolPiece.location!, to: testSquare) == .invalid { continue } // test for off sides of board
case .upLeft, .downLeft, .upRight, .downRight: ()
if isDiagonal(from: foolPiece.location!, to: testSquare) == .invalid { continue } // test for off sides of board
case .invalid: ()
}
testPiece = pieces.first(where: { $0.location == testSquare }) ?? MockData.blankPiece
if testPiece.status != .dead { executeKill(pieceId: testPiece.id, explanation: .blownUp) }
}
executeKill(pieceId: foolPiece.id, explanation: .exploded)
}
forEach
is an array function that iterates over the elements, invoking a closure, like map
; It isn't a Swift loop construct, so you can't use break
or continue
.
Your second attempt is closer to what you need, but unnecessarily complicated. There is no need for an index or raw values.
You can use a for in
loop with a collection's elements directly:
enum directions: Int, CaseIterable {
case up = 0, upRight, right, downRight, down, downLeft, left, upLeft, invalid
}
for direction in directions.allCases {
if direction == .up {
continue
}
print(direction)
}