Reputation: 719
Is there a tidier or better way to write the below nested for...in loops in Swift please? Or is using for...in even the correct way to populate my cards?
for cardNumber in 1...3 {
for cardSymbolIdentifier in 1...3 {
for cardColorIdentifier in 1...3 {
for cardShadingIdentifier in 1...3 {
let card = Card(cardNumber: cardNumber, cardSymbolIdentifier: cardSymbolIdentifier, cardColorIdentifier: cardColorIdentifier, cardShadingIdentifier: cardShadingIdentifier)
deckOfCards.append(card)
}
}
}
}
It definitely does the job, but I can't find anything in the documentation about writing multiple nested loops.
Many thanks in advance, Andy
Upvotes: 7
Views: 5852
Reputation: 426
If you Do that in a single loop, then it become arithmetically complex
for i in 0..<81 {
deckOfCards.append(
Card(cardNumber: i / 27, cardSymbolIdentifier: i/9 % 3,
cardColorIdentifier: i/3 % 3, cardShadingIdentifier: i % 3)
)
}
or
let deckOfCards = (0..<81).map {
Card(cardNumber: $0 / 27, cardSymbolIdentifier: $0/9 % 3,
cardColorIdentifier: $0/3 % 3, cardShadingIdentifier: $0 % 3)
}
In both example - indexing start with 0, so your class init function should shift indexing little
or
add +1 in every parameter before/after passing
Upvotes: 1
Reputation: 299703
There is absolutely nothing wrong with your for loops. They are excellent, well-written Swift. The only problem with your code is that it forces deckOfCards
to be mutable (var), which may be undesirable. If it is, you could use a map
, but I don't consider this particularly better Swift, just slightly different.
let d = (1...3).flatMap { number in
(1...3).flatMap { symbol in
(1...3).flatMap { color in
(1...3).map { shading in
Card.init(cardNumber: number,
cardSymbolIdentifier: symbol,
cardColorIdentifier: color,
cardShadingIdentifier: shading
)}}}}
I would probably write it this second way, but only for stylistic reasons. Your for loops are absolutely fine.
Note @user28434's comment below. My original version of this had a major bug (it returned the wrong type). I've been writing Swift since the day it was released. I teach Swift. I teach functional programming in Swift. And I screwed it up when writing it on the fly. I would never have made that mistake with a simple for loop. There's a major lesson in there.
Upvotes: 3
Reputation: 1435
Your code has no optimisation issues at all according to the need but you can make it a little more elegant or swifty (:p)
let values = [1,2,3]
values.forEach { (cardNumber) in
values.forEach { (cardSymbolIdentifier) in
values.forEach { (cardColorIdentifier) in
values.forEach { (cardShadingIdentifier) in
let card = Card(cardNumber: cardNumber, cardSymbolIdentifier: cardSymbolIdentifier, cardColorIdentifier: cardColorIdentifier, cardShadingIdentifier: cardShadingIdentifier)
deckOfCards.append(card)
}
}
}
}
Upvotes: 0