I'm learning syntax of Swift and wonder, why the following code isn't working as I expect it to:
for i in 1...100{
switch (i){
case 1:
Int(i%3) == 0
println("Fizz")
case 2:
Int(i%5) == 0
println("Buzz")
default:
println("\(i)")
}
}
I want to print Fizz every time number is divisible by 3 (3, 6, 9, 12, etc) and print Buzz every time it's divisible by 5. What piece of the puzzle is missing?
Note: I did solve it using the following:
for ( var i = 0; i < 101; i++){
if (Int(i%3) == 0){
println("Fizz")
} else if (Int(i%5) == 0){
println("Buzz")
} else {
println("\(i)")
}
}
I want to know how to solve this using Switch. Thank you.
The usual rules for the FizzBuzz game
are to replace every multiple of 3 by "Fizz", every multiple of 5 by "Buzz", and
every multiple of both 3 and 5 by "FizzBuzz".
This can be done with a switch statement on the tuple (i % 3, i % 5).
Note that _ means "any value":
for i in 1 ... 100 {
switch (i % 3, i % 5) {
case (0, 0):
print("FizzBuzz")
case (0, _):
print("Fizz")
case (_, 0):
print("Buzz")
default:
print(i)
}
}
Switch statements in Swift support value bindings.
This allows you to assign a value that matches a certain condition (evaluated via the where clause) to a temporary variable (x & y here):
for i in 1...100 {
switch (i){
case let x where x%3 == 0:
println("Fizz")
case let y where y%5 == 0:
println("Buzz")
default:
println("\(i)")
}
}
You could also use the assigned temp value in the case body.
Update:
Matt Gibson points out in the comments, that you can omit the assignment to a temp var if you are not going to use it in the case body.
So a more concise version of the above code would be:
for i in 1...100 {
switch (i){
case _ where i%3 == 0:
println("Fizz")
case _ where i%5 == 0:
println("Buzz")
default:
println("\(i)")
}
}
Side note: Your 2 code samples are slightly different (the first one uses the range 0-100 as input, while the second one operates on 1-100). My sample is based on your first code snippet.
This is a more general answer for people who come here just wanting to know how to use the switch statement in Swift.
General usage
switch someValue {
case valueOne:
// executable code
case valueTwo:
// executable code
default:
// executable code
}
Example
let someValue = "horse"
switch someValue {
case "horse":
print("eats grass")
case "wolf":
print("eats meat")
default:
print("no match")
}
Notes:
No break statement is necessary. It is the default behavior. Swift switch cases do not "fall through". If you want them to fall through to the code in the next case, you must explicitly use the fallthrough keyword.
Every case must include executable code. If you want to ignore a case, you can add a single break statement.
The cases must be exhaustive. That is, they must cover every possibly value. If it is not feasible to include enough case statements, a default statement can be included last to catch any other values.
The Swift switch statement is very flexible. The following sections include some other ways of using it.
Matching multiple values
You can match multiple values in a single case if you use separate the values with commas. This is called a compound case.
let someValue = "e"
switch someValue {
case "a", "b", "c":
// executable code
case "d", "e":
// executable code
default:
// executable code
}
You can also match whole intervals.
let someValue = 4
switch someValue {
case 0..<10:
// executable code
case 10...100:
// executable code
default:
// executable code
}
You can even use tuples. This example is adapted from the documentation.
let aPoint = (1, 1)
switch aPoint {
case (0, 0):
// only catches an exact match for first and second
case (_, 0):
// any first, exact second
case (-2...2, -2...2):
// range for first and second
default:
// catches anything else
}
Value Bindings
Sometimes you might want to create a temporary constant or variable from the switch value. You can do this right after the case statement. Anywhere that a value binding is used, it will match any value. This is similar to using _ in the tuple example above. The following two examples are modified from the documentation.
let anotherPoint = (2, 0)
switch anotherPoint {
case (let x, 0):
// can use x here
case (0, let y):
// can use y here
case let (x, y):
// can use x or y here, matches anything so no "default" case is necessary
}
You can further refine the matching by using the where keyword.
let yetAnotherPoint = (1, -1)
switch yetAnotherPoint {
case let (x, y) where x == y:
// executable code
case let (x, y) where x == -y:
// executable code
case let (x, y):
// executable code
}
Further study
This answer was meant to be a quick reference. Please read the full documentation for more. It isn't difficult to understand.
This is how it can be done
var i = 0
switch i {
case i where i % 5 == 0 && i % 3 == 0: print(" Fizz Buzz")
case i where i % 3 == 0 : print("Fizz")
case i where i % 5 == 0 : print("Buzz")
default: print(i)
}
The industry standard behaviour of switch can lead to bugs similar to "Go to Fail".
Basically the code doesn't always do exactly what it looks like the code will do when reading over it, which leads to code auditors skipping over critical bugs.
To counter that, Apple has decided switch statements should not work the same in Swift as the industry standard. In particular:
There is an automatic break at the end of every case. It's impossible for more than one case statement to execute.
If it's theoretically possible for one of the case statements to be missed, then the code will not compile at all. In swift one of the case statements will always execute, no matter what value is provided. If you provide an enum, every enum value must be handled. If a new value is added to an existing enum the code won't compile until new case statements are added. If you provide a 32 bit integer, you must handle every possible value of a 32 bit int.
Here are the two ways I use switch statement for this kind of problems .
1>> Using where keyword
func printNumberType(number : Int){
switch number {
case number where number % 3 == 0 && number % 5 == 0 :
print("foo bar")
case number where number % 3 == 0 :
print("foo")
case number where number % 5 == 0 :
print("bar")
default :
print("Number is not divisible by 3 and 5")
}
}
2>> Using values combination
func printNumberByMultipleValues(number : Int){
let combination = (number % 3,number % 5)
switch combination {
case (0,0):
print("foo bar")
case (0,_) :
print("foo")
case (_,0) :
print("bar")
default :
print("Number is not divisible by 3 and 5")
}
}
Here is closer example for multiple value type .
var printNumberByMultipleValues : (Int)->() = { number in
let combination = (number % 3,number % 5)
switch combination {
case (0,0):
print("foo bar")
case (0,_) :
print("foo")
case (_,0) :
print("bar")
default :
print("Number is not divisible by 3 and 5")
}
}
Use this code. Your logic is wrong. Your Switch Statement does not find the case accept 1 and 2
class TEST1{
func print() -> Void{
var i = 0
for i in 1...100{
if Int(i%3) == 0 {
println("Fizz")
}
else if Int(i%5) == 0{
println("Buzz")
}
else {
println("\(i)")
}
}
}
}
var x = TEST1()
x.print()
Related
I have to make a game for my online course, it displays on the console it's a game for 2 players with 3 characters for each team and I'm struggling how can i make a loop in my switch to "force" the player to choose between 1, 2 or 3 (it symbolize the characters of his team) to attack the enemy team, here's my code :
func chooseChar(charac: inout[Character]){
let choice = readLine()
var attacker: Character
switch choice {
case "1":
attacker = self.playerTeam[0]
charac.append(attacker)
case "2":
attacker = self.playerTeam[1]
charac.append(attacker)
case "3":
attacker = self.playerTeam[2]
charac.append(attacker)
default: print("choose between 1 2 3")
}
}
Actually, when the player choose for example 4 it goes on the default and my code stop...
Anybody have an idea ? sorry for my bad english !
Thanks !
Use a classic C way and add while(true) make things easier like this.
func chooseChar(charac: inout[Character]){
while (true){
let choice = readLine()
var attacker: Character
switch choice {
case "1":
attacker = self.playerTeam[0]
charac.append(attacker)
return
case "2":
attacker = self.playerTeam[1]
charac.append(attacker)
return
case "3":
attacker = self.playerTeam[2]
charac.append(attacker)
return
default: print("choose between 1 2 3")
}
}
}
As per your requirement you can call the same function in default case (use recursion)(this will make your code running until any case1,case2,or case3 occurs), or you can set a parameter in default case and check outside the switch and make action according to that.
i have code like this
switch thing {
case thisThing:
do thing #1
do thing #2
case thatThing:
do thing #2
do thing #3
case anotherThing:
do thing #4
default:
default
}
So, EVERY case has something that ONLY IT does. Some cases also do the same things as one or more other cases.
Is there a way to accomplish this if I don't want any repetitive code?
OR, is there a much more efficient way of doing this without switch statements at all?? I mean, I could, for example, use if statements, but like switch statements, I can't think of a way to accomplish what I want without using repetitive code.
also, this example might be more clear than the above
myFavoriteNumbers = []
myLeastFavoriteNumbers = []
switch myNumber {
case 1:
print("my number is number 1") // do this only for case 1
myFavoriteNumbers += [1] // do this for case 1 and case 2
case 2:
print("this is number 2") // do this only for case 2
myFavoriteNumbers += [2] // do this for case 1 and case 2
case 3:
print("I don't like number 3") // do this only for case 3
myLeastFavoriteNumbers += [3] // do this for case 3 and case 4
case 4:
print("Number Four") // do this only for case 4
myLeastFavoriteNumbers += [4] // do this for case 3 and case 4
default:
print("Default")
}
You can use an initial separate pattern matching statement (comparable to a single case independent from the switch statement) that covers the actions that are unique for any (valid) number, and let the switch statement follow with cases that handle actions that are common for several numbers. With this you separate the unique and common logic action, where the latter is simply implemented as usual cases for any pattern matching switch implementation.
E.g., for your example
var myFavoriteNumbers: [Int] = []
var myLeastFavoriteNumbers: [Int] = []
let myNumberDescriptions = ["my number is number 1",
"this is number 2", "I don't like number 3", "Number Four"]
let myNumber = 1
/* unique action:
perform a unique action (given a valid number)
and thereafter proceed to common cases */
if 1...myNumberDescriptions.count ~= myNumber {
print(myNumberDescriptions[myNumber-1])
}
/* common cases */
switch myNumber {
/* common case: is a favourite number */
case 1...2: myFavoriteNumbers += [myNumber]
/* common case: is a least favourite number */
case 3...4: myLeastFavoriteNumbers += [myNumber]
default:
print("Default")
}
In case the action that is unique to any number is more complex, use the same approach as above, but use more advanced logic (e.g. an event handler) for the unique action "case".
You could nest switch statements that switch on the same value, like this:
switch myNumber {
case 1...2:
myFavoriteNumbers += [myNumber] // do this for case 1 and case 2
switch myNumber {
case 1:
print("my number is number 1") // do this only for case 1
default:
print("this is number 2") // do this only for case 2
}
case 3...4:
myLeastFavoriteNumbers += [myNumber] // do this for case 3 and case 4
switch myNumber {
case 3:
print("I don't like number 3") // do this only for case 3
default:
print("Number Four") // do this only for case 4
}
default:
print("Default")
}
Not the most elegant bit of code you'll ever see, but it achieves what you want to achieve without the repetition.
Fallthrough comes to mind as an obvious solution, but as somebody here already said it does not work in a way that would be helpful.
I don't have any silver bullet for you but I think I would go about this in such a way:
create one switch statement which only covers separate logic
create a second switch statement which combines common logic
switch thing {
case thisThing:
do thing #1
case thatThing:
do thing #4
case anotherThing:
do thing #5
default: ()
}
switch thing {
case thisThing, thatThing:
do thing #2
default: ()
}
It would work when your logic does not depend on the order of function calls (which it should not, if it does it may be a sign to improve your code design). To me it looks clean, however it's still not ideal..
I found this code at apple swift documentation
indirect enum ArithmeticExpression {
case Number(Int)
case Addition(ArithmeticExpression, ArithmeticExpression)
case Multiplication(ArithmeticExpression, ArithmeticExpression)
}
func evaluate(expression: ArithmeticExpression) -> Int {
switch expression {
case .Number(let value):
return value
case .Addition(let left, let right):
return evaluate(left) + evaluate(right)
case .Multiplication(let left, let right):
return evaluate(left) * evaluate(right)
}
}
// evaluate (5 + 4) * 2
let five = ArithmeticExpression.Number(5)
let four = ArithmeticExpression.Number(4)
let sum = ArithmeticExpression.Addition(five, four)
let product = ArithmeticExpression.Multiplication(sum, ArithmeticExpression.Number(2))
print(evaluate(product))
// prints "18"
i don't quit understand how the recursion is happening in here and why a constant declaration is being declared as a parameter in the return statement in the returning line ?
Think of it as a tree. Nodes=Expressions. Constants=Leaves.
(image source ruslanspivak.com)
While traversing it - you examine each of the two operands. If it's an expression, you need to compute it, so you call on 'evaluate' with this operand. If it's a constant, think of it like a result - it's just a number, so no more calculations are needed.
In the end, we ALWAYS get to a constants (=leaves) it is then when the the stack starts to fold and the values results return "up" in the tree to add up to the total result.
For more diving into the subject I recommend googling "binary expression tree".
(By the way, the code example does not tend for priorities. The multiplication is computed before the addition only because the order of calls.
If we really wanted to take care of priorities : e.g. "(", ")" over "*" , "/", a stack for operations would have been needed here.)
Is it possible to break from a Groovy .each{Closure}, or should I be using a classic loop instead?
Nope, you can't abort an "each" without throwing an exception. You likely want a classic loop if you want the break to abort under a particular condition.
Alternatively, you could use a "find" closure instead of an each and return true when you would have done a break.
This example will abort before processing the whole list:
def a = [1, 2, 3, 4, 5, 6, 7]
a.find {
if (it > 5) return true // break
println it // do the stuff that you wanted to before break
return false // keep looping
}
Prints
1
2
3
4
5
but doesn't print 6 or 7.
It's also really easy to write your own iterator methods with custom break behavior that accept closures:
List.metaClass.eachUntilGreaterThanFive = { closure ->
for ( value in delegate ) {
if ( value > 5 ) break
closure(value)
}
}
def a = [1, 2, 3, 4, 5, 6, 7]
a.eachUntilGreaterThanFive {
println it
}
Also prints:
1
2
3
4
5
Replace each loop with any closure.
def list = [1, 2, 3, 4, 5]
list.any { element ->
if (element == 2)
return // continue
println element
if (element == 3)
return true // break
}
Output
1
3
No, you can't break from a closure in Groovy without throwing an exception. Also, you shouldn't use exceptions for control flow.
If you find yourself wanting to break out of a closure you should probably first think about why you want to do this and not how to do it. The first thing to consider could be the substitution of the closure in question with one of Groovy's (conceptual) higher order functions. The following example:
for ( i in 1..10) { if (i < 5) println i; else return}
becomes
(1..10).each{if (it < 5) println it}
becomes
(1..10).findAll{it < 5}.each{println it}
which also helps clarity. It states the intent of your code much better.
The potential drawback in the shown examples is that iteration only stops early in the first example. If you have performance considerations you might want to stop it right then and there.
However, for most use cases that involve iterations you can usually resort to one of Groovy's find, grep, collect, inject, etc. methods. They usually take some "configuration" and then "know" how to do the iteration for you, so that you can actually avoid imperative looping wherever possible.
Just using special Closure
// declare and implement:
def eachWithBreak = { list, Closure c ->
boolean bBreak = false
list.each() { it ->
if (bBreak) return
bBreak = c(it)
}
}
def list = [1,2,3,4,5,6]
eachWithBreak list, { it ->
if (it > 3) return true // break 'eachWithBreak'
println it
return false // next it
}
You can't break from a Groovy each loop, but you can break from a java "enhanced" for loop.
def a = [1, 2, 3, 4, 5, 6, 7]
for (def i : a) {
if (i < 2)
continue
if (i > 5)
break
println i
}
Output:
2
3
4
5
This might not fit for absolutely every situation but it's helped for me :)
I agree with other answers not to use an exception to break an each. I also do not prefer to create an extra closure eachWithBreak, instead of this I prefer a modern approach: let's use the each to iterate over the collection, as requested, but refine the collection to contain only those elements to be iterated, for example with findAll:
collection.findAll { !endCondition }.each { doSomething() }
For example, if we what to break when the counter == 3 we can write this code (already suggested):
(0..5)
.findAll { it < 3 }
.each { println it }
This will output
0
1
2
So far so good, but you will notice a small discrepancy though. Our end condition, negation of counter == 3 is not quite correct because !(counter==3) is not equivalent with it < 3. This is necessary to make the code work since findAll does not actually break the loop but continues until the end.
To emulate a real situation, let's say we have this code:
for (n in 0..5) {
if (n == 3)
break
println n
}
but we want to use each, so let's rewrite it using a function to simulate a break condition:
def breakWhen(nr) { nr == 3 }
(0..5)
.findAll { !breakWhen(it) }
.each { println it }
with the output:
0
1
2
4
5
now you see the problem with findAll. This does not stop, but ignores that element where the condition is not met.
To solve this issues, we need an extra variable to remember when the breaking condition become true. After this moment, findAll must ignore all remaining elements.
This is how it should look like:
def breakWhen(nr) { nr == 3 }
def loop = true
(0..5)
.findAll {
if (breakWhen(it))
loop = false
!breakWhen(it) && loop
} .each {
println it
}
with the output:
0
1
2
That's what we want!
(1..10).each{
if (it < 5)
println it
else
return false
You could break by RETURN. For example
def a = [1, 2, 3, 4, 5, 6, 7]
def ret = 0
a.each {def n ->
if (n > 5) {
ret = n
return ret
}
}
It works for me!
In Swift, I need to make a switch like this:
switch char {
case "+": statement 1; statement 3
case "-": statement 2; statement 3
default: statement 3
}
However, I don't want to copy the statement 3, because it is actually quite long, so I'm looking for an alternative way (if it exists) to somehow make the switch check every case condition, and execute the default too.
Repeated code? Good candidate for a local function:
func statement3() {
// ... lots of stuff here ...
}
switch char {
case "+": statement 1; statement3()
case "-": statement 2; statement3()
default: statement3()
}
But if you really want to do statement3 in every case, then just take it out of the switch statement altogether:
switch char {
case "+": statement 1
case "-": statement 2
default: break
}
statement 3
The only way you can fallthrough a case and skip over the next one to get you to default is to retest the condition:
switch char {
case "+": statement 1; fallthrough
case "-": if char == "-" { statement 2 }; fallthrough
default: statement 3
}
which at the end of the day, let's be honest, looks awesomely frugly. I suggest you replace your long statements by function calls and keep the control flow you gave above.