How do I use a boolean operator in a case statement? - objective-c

I just Don't understand how to use a boolean operator inside a switch statement
switch (expression) {
case > 20:
statements
break;
case < -20:
statements
break;
}
Edit:
I don't want an If () statement.

You can't. Use if() ... else ....
The nearest thing available to what you want uses a GCC extension and is thus non-standard. You can define ranges in case statements instead of just a value:
switch(foo)
{
case 0 ... 20: // matches when foo is inclusively comprised within 0 and 20
// do cool stuff
break;
}
However, you can't use that to match anything under a certain value. It has to be in a precise range. Switches can only be used to replace the comparison operator against a constant, and can't be used for anything more than that.

switch ((expression) > 20) {
case true:
statements
break;
case false:
default:
statements
break;
}
What.. you want more than 1 boolean in a case? You could do this
int ii = ((expression) > 20) + 2 * ((expression) < -20);
switch (ii) {
case 1:
statements
break;
case 2:
statements
break;
}
This, IMO is pretty bad code, but it is what you asked for...
Just use the if statement, you'll be better off in the long run.

Related

How to reduce a string to ASCII 7 characters for indexing purposes?

I am working on an application which must index certain sentences. Currently using Java and PostgreSQL. The sentences may be in several languages like French and Spanish using accents and other non-ASCII symbols.
For each word I want to create an index-able equivalent so that a user can perform a search insensitive to accents (transliteration). For example, when the user searches "nacion" it must find it even if the original word stored by the application was "Nación".
What could be the best strategy for this? I am not necessarily restricted only to PostgreSQL, nor the internal indexed value needs to have any similarity with the original word. Ideally, it should be a generic solution for converting any Unicode string into an ASCII string insensitive to case and accents.
So far I am using a custom function shown below which naively just replaces some letters with ASCII equivalents before storing the indexed value and does the same on query strings.
public String toIndexableASCII (String sStrIn) {
if (sStrIn==null) return null;
int iLen = sStrIn.length();
if (iLen==0) return sStrIn;
StringBuilder sStrBuff = new StringBuilder(iLen);
String sStr = sStrIn.toUpperCase();
for (int c=0; c<iLen; c++) {
switch (sStr.charAt(c)) {
case 'Á':
case 'À':
case 'Ä':
case 'Â':
case 'Å':
case 'Ã':
sStrBuff.append('A');
break;
case 'É':
case 'È':
case 'Ë':
case 'Ê':
sStrBuff.append('E');
break;
case 'Í':
case 'Ì':
case 'Ï':
case 'Î':
sStrBuff.append('I');
break;
case 'Ó':
case 'Ò':
case 'Ö':
case 'Ô':
case 'Ø':
sStrBuff.append('O');
break;
case 'Ú':
case 'Ù':
case 'Ü':
case 'Û':
sStrBuff.append('U');
break;
case 'Æ':
sStrBuff.append('E');
break;
case 'Ñ':
sStrBuff.append('N');
break;
case 'Ç':
sStrBuff.append('C');
break;
case 'ß':
sStrBuff.append('B');
break;
case (char)255:
sStrBuff.append('_');
break;
default:
sStrBuff.append(sStr.charAt(c));
}
}
return sStrBuff.toString();
}
String s = "Nación";
String x = Normalizer.normalize(s, Normalizer.Form.NFD);
StringBuilder sb=new StringBuilder(s.length());
for (char c : x.toCharArray()) {
if (Character.getType(c) != Character.NON_SPACING_MARK) {
sb.append(c);
}
}
System.out.println(s); // Nación
System.out.println(sb.toString()); // Nacion
How this works:
It splits up international characters to NFD decomposition (ó becomes o◌́), then strips the combining diacritical marks.
Character.NON_SPACING_MARK contains combining diacritical marks (Unicode calls it Bidi Class NSM [Non-Spacing Mark]).
The one obvious improvement for your current code: use a Map<Character, Character> that you prefill with your mappings.
And then simply check if that Map has a mapping; of so; use that; otherwise use the original character.
And as Androbin explains, there are special maps that do not rely on objects, but work with primitive types, like this trove. So, depending on your solution and requirements; you could look into that.

Use variables as case constants in swich statement

I'm trying to use a variable as the case match, however I get "Expression is not an integer in Objective-C.
Is it possible to use variable in switches in this manner?
int count = [array count];
switch ([number to check]) {
case 0:
//first statement
break;
case 1 ... (count -1):
//somewhere between 1 and the next to last statement
//Basically the middle
break;
case count:
//Last statement
default:
break;
}
Objective-C (and C) switch only supports a single primitive constant value for each case statement (or a range as pointed out in the answer by TwoStraws). You would be much better off writing your code using if/else:
if ([number to check] == 0) {
} else if ([number to check] >= 1 && [number to check] < count) {
} else if ([number to check] == count) {
} else {
}
Objective-C's switch statement does support ranges of values as you've seen, but doesn't support variable matches I'm afraid.
So, the below code is valid because I've used exact integers:
int numberOfKittens = 12;
NSString *kittenDescription;
switch (numberOfKittens) {
case 0 ... 5:
kittenDescription = #"Need more kittens";
break;
case 6 ... 10:
kittenDescription = #"That's a good number of kittens.";
break;
case 11 ... 20:
kittenDescription = #"Are you sure you can handle that many kittens?";
break;
default:
kittenDescription = #"You must really love kittens!";
}
…but trying to put a variable in place of any of those will fail.
If this is something you desperately want, consider using Swift because it has a much more expressive switch matching system. Here's that same code in Swift, now with a variable being used to match a case:
let upperLimit = 20
let numberOfKittens = 19
var kittenDescription = ""
switch (numberOfKittens) {
case 0 ... 5:
kittenDescription = "Need more kittens"
case 6 ... 10:
kittenDescription = "That's a good number of kittens."
case 11 ... upperLimit:
kittenDescription = "Are you sure you can handle that many kittens?"
default:
kittenDescription = "You must really love kittens!"
}

error with switch case and exptected expression

Sorry to ask this (I rarely use switch statements) but I am getting an error with this but it seems valid to me (but obviously isn't):
NSInteger section=indexPath.section;
switch(section){
case 0:
Item *mi = self.miArray[indexPath.row]; // <- expected expression
...
return cell;
break;
case 1:
Item *mi = self.miArray[indexPath.row];
break;
}
What am I doing wrong?
You can either put the case in braces (case 0: { Item *mi ... }) or add a ; after the case statement (case 0:;).
Either of that should help but I actually forgot why this is necessary.
Found an explanation here: Weird Switch error in Obj-C
Declaration is not allowed within switch.
Declare Item before entering to switch and do the initialization within the switch.

How to compare strings instead of integers in switch case?

I have this code who try to compare strings in Switch Case:
char input[50+1];
fgets( input, 50, stdin );
switch (input) {
case "register": NSLog(#"Voce escolheu a opcao de cadastro");
break;
case "enter": NSLog(#"Voce escolheu a opcao de entrada");
break;
case "exit": NSLog(#"Voce escolheu a opcao de saida");
break;
}
This command returns me an error, because I believe that we can not write a text after the 'case' command. I would have someone could help me solve this problem, I believe there are other ways to make a Switch Case using strings, but how?
The lookup option works pretty well. Consider:
NSArray *strings = #{#"string1", #"string2"};
NSUInteger index = [strings indexOfObject:input];
switch(index) {
case 0:
//stuff for string 1;
case 1:
// stuff for string 2:
case NSNotFound:
// not found;
}
You can't. Switch only works with integers. The best options are a chain of if-else statements or a lookup table (e.g. an NSDictionary).

Group case in a Switch/Case statement in objective-c [duplicate]

This question already has answers here:
Switch statement syntax for same action through different cases
(2 answers)
Closed 9 years ago.
I have a switch case where at different case may correspond the same fragment of code.
Is there an elegant alternative, rather than duplicating all the code ?
switch(expression) {
case firstCase:
// do something
break;
case secondCase:
// do exactly the same of first case
break;
case otherCase:
// do anything else
break;
case etceteraCase:
.......
default:
break;
}
I know that as an alternative I could create a method to be called within the case, but this could lead to proliferation of methods hard to maintain.
Yes:
switch(expression) {
case firstCase:
case secondCase:
// do exactly the same of first case
break;
case otherCase:
case yetAnotherCase:
// do anything else
break;
case etceteraCase:
.......
default:
break;
}
Remove break after first case:
switch(expression) {
case firstCase:
case secondCase:
// do the same of first case
break;
case otherCase:
// do anything else
break;
case etceteraCase:
.......
default:
break;
}
switch(expression) {
case firstCase:
case secondCase:
// do exactly the same of first case
break;
case otherCase:
// do anything else
break;
case etceteraCase:
.......
default:
break;
}
excluding break; will produce your expected result.