swift 1.2 if loop to switch statement - swift

I have the following If-Statment and I was wondering how this could be achieved with a switch statement?
I am trying to represent an integer value within an array as a string (e.g. 1 == "Jan")
func assigningMonthName([Data]) {
for i in dataset.arrayOfDataStructures {
if (i.month) == 1 {
println("Jan")
}
else if (i.month) == 2 {
print("Feb")
}
else if (i.month) == 3 {
print("March")
}
else if (i.month) == 4 {
print("April")
}
else if (i.month) == 5 {
print("May")
}
else if (i.month) == 6 {
print("June")
}
else if (i.month) == 7 {
print("July")
}
else if (i.month) == 8 {
print("August")
}
else if (i.month) == 9 {
print("September")
}
else if (i.month) == 10 {
print("October")
}
else if (i.month) == 11 {
print("November")
}
else if (i.month) == 12 {
print("December")
}
else {
println("Error assigning month name")
}
}
}
any answers would be appreciated :)

While you can use a switch, this is essentially just another way to write if-else so there is no big improvement to your code:
switch i.month {
case 1:
print("Jan")
case 2:
print("Feb")
...
}
What about using an array?
let monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "Sept", "October", "November", "December"]
print(monthNames[i.month - 1])
The system actually already contains month names, they are even localized:
let monthNames = NSDateFormatter().monthSymbols;
print(monthNames[i.month - 1])

Try this:
switch i.month {
case 1:
print("Jan")
case 2:
print("Feb")
...
default:
print("default value")
}

Related

Flutter how to create a loop in else if

i got a chart that display months (in french) when i go below the month == 1, i would like to go back to my current month and not see my 'error'.
Is there a method to make it ?
String numericToStringMonth(int month) {
if (month < 1 || month > 12) {
return 'error';
} else if (month == 1) {
return 'Janvier';
} else if (month == 2) {
return 'Février';
} else if (month == 3) {
return 'Mars';
} else if (month == 4) {
return 'Avril';
} else if (month == 5) {
return 'Mai';
} else if (month == 6) {
return 'Juin';
} else if (month == 7) {
return 'Juillet';
} else if (month == 8) {
return 'Août';
} else if (month == 9) {
return 'Septembre';
} else if (month == 10) {
return 'Octobre';
} else if (month == 11) {
return 'Novembre';
} else if (month == 12) {
return 'Décembre';
} else {
return 'error';
}
}
String numericToStringMonth(int month) {
// make list of months for easier access
List<String> months = [
'Janvier',
'Février',
'Mars',
'Avril',
'Mai',
'Juin',
'Juillet',
'Août',
'Septembre',
'Octobre',
'Novembre',
'Décembre'
];
int currentMonth = month - 1;
try {
if (currentMonth > 11) {
throw Exception('Month must be between 1 and 12');
} else if (currentMonth < 0) {
// setting month to the first one when value goes below 0, add your logic here
currentMonth = 1;
}
return months[currentMonth];
} catch (e) {
print(e);
}
return '';
}

Is there any way to simplify complex if else statement in swift?

I have a long if else condition to assign a text to a UILabel. So i am looking for a better option/logic to write less number of lines.
Below is my condition,
if numberOfTeachers == 4 && numberOfStudents == 27 {
if String(interval.day! + 1) == "1" {
self.daysLabel.text = "1st"
self.testLabel.isHidden = true
self.subjectLabel.text = "Physics"
self.dayTitleLabel.text = "Today is your first day"
} else if String(interval.day! + 1) == "2" {
self.daysLabel.text = "2nd"
self.testLabel.isHidden = true
self.subjectLabel.text = "Chemistry"
self.dayTitleLabel.text = "Today is your Second day"
} else if String(interval.day! + 1) == "3" {
self.daysLabel.text = "3rd"
self.subjectLabel.isHidden = true
self.unitLabel.text = "Mathematics"
self.dayTitleLabel.text = "Today is your Third day"}
else if String(interval.day! + 1) == "4" {
self.daysLabel.text = "4th"
self.testLabel.isHidden = false
self.subjectLabel.text = "Physics"
self.dayTitleLabel.text = "Today is your fourth day" }
else if numberOfTeachers == 4 && numberOfStudents == 28 {
} else if numberOfTeachers == 4 && numberOfStudents == 29 {
} else if numberOfTeachers == 4 && numberOfStudents == 30 {
} else if numberOfTeachers == 5 && numberOfStudents == 27 {
} else if numberOfTeachers == 5 && numberOfStudents == 28 {
} else if numberOfTeachers == 5 && numberOfStudents == 29 {
} else if numberOfTeachers == 5 && numberOfStudents == 30 {
} else if numberOfTeachers == 6 && numberOfStudents == 27 {
} else if numberOfTeachers == 6 && numberOfStudents == 28 {
} else if numberOfTeachers == 6 && numberOfStudents == 29 {
} else if numberOfTeachers == 6 && numberOfStudents == 30 {
} else if numberOfTeachers == 7 && numberOfStudents == 27 {
} else if numberOfTeachers == 7 && numberOfStudents == 28 {
} else if numberOfTeachers == 7 && numberOfStudents == 29 {
} else if numberOfTeachers == 7 && numberOfStudents == 30 {
}
there are atleast 4 more conditions inside every if condition like (4,27), (4,28) , (5,27), (5,28)....so on.
So this whole condition is getting too long.
You could nest the if conditions like:
if numberOfTeachers == 4
{
if numberOfStudents == 29 {}
else if ...
}
else if ...
You could also use a switch statement which is a great alternative for long chains of if-else:
switch numberOfTeachers
{
case value 4:
// handle number of students
case value 5:
...
default:
// error?
}
Edit as Martin R noted, one could also use:
switch (numberOfTeachers, numberOfStudents)
{
case (4, 27):
// handle number of students
case (5, 28):
...
default:
// error?
}

My logic for seeing if a user has won a tic-tac-toe match isn't working [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
Below is some code to check if somebody has won on a tic tac toe board. (board[0] - board[8] represent the tic tac toe board from top to bottom, left to right):
func checkWin(board: [Int]) -> Bool{
if board[0] != 0 {
if board[0] == board[1] && board[1] == board[2] {
return true
} else if board[0] == board[3] && board[3] == board[6] {
return true
}
} else if board[4] != 0 {
if board[1] == board[4] && board[4] == board[7] {
return true
} else if board[3] == board[4] && board[4] == board[5] {
return true
} else if board[2] == board[4] && board[4] == board[6] {
return true
} else if board[0] == board[4] && board[4] == board[8] { //
return true
}
} else if board[8] != 0 {
if board[2] == board[5] && board[5] == board[8] { //
return true
} else if board[6] == board[7] && board[7] == board[8] { //
return true
}
}
return false
}
However, the three lines with // at the end will not return true even if the conditions are met. I have noticed that they all share board[8], however I know this is not a problem with the storyboard, as if I hard code a win that satisfies one of faulty conditions it still doesn't work. Can anyone see what's going wrong?
Your logic is flawed. Once you check with the outer ifs, you have committed to just checking a few of the possible cases.
For instance, if space 0 is not empty, then you are only checking cases 0-1-2 and 0-3-6, but you aren't checking 0-4-8 so you'll miss that possibility. The 0-4-8 case is handled inside the first else if case, but you'll never get there if board[0] != 0.
You can fix this by using 3 ifs instead of the else ifs.
func checkWin(board: [Int]) -> Bool{
print(board)
if board[0] != 0 {
if board[0] == board[1] && board[1] == board[2] {
return true
} else if board[0] == board[3] && board[3] == board[6] {
return true
}
}
if board[4] != 0 {
if board[1] == board[4] && board[4] == board[7] {
return true
} else if board[3] == board[4] && board[4] == board[5] {
return true
} else if board[2] == board[4] && board[4] == board[6] {
return true
} else if board[0] == board[4] && board[4] == board[8] { //
return true
}
}
if board[8] != 0 {
if board[2] == board[5] && board[5] == board[8] { //
return true
} else if board[6] == board[7] && board[7] == board[8] { //
return true
}
}
return false
}
a little bit more compact:
func checkWin(board: [Int]) -> Bool{
let checks = [
//rows
[0,1,2],
[3,4,5],
[6,7,8],
//columns
[0,3,6],
[1,4,7],
[2,5,8],
//cross
[0,4,8],
[2,4,6]
]
for check in checks{
if board[check[0]] != 0
&& board[check[0]] == board[check[1]]
&& board[check[1]] == board[check[2]]
{
return true
}
}
return false
}
better to get also the winner-id or 0 for no winner:
func getWinner(board: [Int]) -> Int{
let checks = [
//rows
[0,1,2],
[3,4,5],
[6,7,8],
//columns
[0,3,6],
[1,4,7],
[2,5,8],
//cross
[0,4,8],
[2,4,6]
]
for check in checks{
if board[check[0]] != 0
&& board[check[0]] == board[check[1]]
&& board[check[1]] == board[check[2]]
{
return board[check[0]]
}
}
return 0
}
or if you like to put it in an enum:
enum Winner {
case none
case player(id: Int)
}
func checkWin(board: [Int]) -> Winner{
let checks = [
//rows
[0,1,2],
[3,4,5],
[6,7,8],
//columns
[0,3,6],
[1,4,7],
[2,5,8],
//cross
[0,4,8],
[2,4,6]
]
for check in checks{
if board[check[0]] != 0
&& board[check[0]] == board[check[1]]
&& board[check[1]] == board[check[2]]
{
return .player(id: board[check[0]])
}
}
return .none
}

Using If statement to check against 3 possibilities

I am wanting to compare three randomly generated numbers to see if any two of them are equal. I have an if statement that works but I would really like to combine the two else if statements into one if possible. I am thinking there has to be some way to use or but its only a binary operator. is there a way to use ? and make a ternary argument in one else if statement?
if aRand == bRand && bRand == cRand{
resultLabel.text = "3 out of 3"
} else if
(aRand == bRand || aRand == cRand) {
resultLabel.text = "2 out of 3"
} else if
(bRand == cRand) {
resultLabel.text = "2 out of 3"
} else {
resultLabel.text = "No Match"
}
Actually it's
if aRand == bRand || aRand == cRand || bRand == cRand
Here a swiftier expression
let rand = (aRand, bRand, cRand)
switch rand {
case let (a, b, c) where a == b && b == c : resultLabel.text = "3 out of 3"
case let (a, b, c) where a == b || a == c || b == c : resultLabel.text = "2 out of 3"
default : resultLabel.text = "No match"
}
Shorter way:
if (aRand == bRand && bRand == cRand) {
resultLabel.text = "3 out of 3"
} else if (aRand == bRand || bRand == cRand || aRand == cRand) {
resultLabel.text = "2 out of 3"
} else {
resultLabel.text = "No Match"
}
If I understand your algorithm correctly, you can avoid if altogether:
let aRand = 0
let bRand = 1
let cRand = 1
let allValues = [aRand, bRand, cRand]
let uniqueValues = Set(allValues)
let text: String
if (uniqueValues.count == allValues.count) {
text = "No match"
} else {
text = String(format: "%i out of %i", allValues.count - uniqueValues.count + 1, allValues.count)
}
print(text)
This will work for any number of values.

check var in between

if (%var == 1 or 2 or 3 or 4 or 5) { }
So what u want is to check whether the variable's value is in between 1-5 in mirc?
I can do it like this:
if (%var == 1) { }
if (%var == 2) { }
if (%var == 3) { }
if (%var == 4) { }
if (%var == 5) { }
But is there any shorter way?
The idiomatic answer is:
if (%var isnum 1-5) {
}