Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
In Xcode, I have an if and an else statement.
I would like to make the statement have multiple conditions, but only one of them have to be 'YES'.
For example:
I have a NSString, the value of that string is:
[NSstring stringWithFormat:#"ABCDEFG12345"];
I need to have my if statement check for if A or 1 or 5 is in the string. I understand how to use [string rangeOfString:#"CheckHere"];.
I need my if statement to find one or all of those given letters/numbers. If one is found, execute the given code, if two are found, execute the given code, if all three are found, execute the given code.
You need no if-else. You can do something like this.
NSString* string = #"ABCDEFG12345";
int foundA = [string rangeOfString:#"A"].location == NSNotFound ? 0 : 1;
int found1 = [string rangeOfString:#"1"].location == NSNotFound ? 0 : 1;
int found5 = [string rangeOfString:#"5"].location == NSNotFound ? 0 : 1;
int foundCount = foundA + found1 + found5;
switch(foundCount) {
case 1: [self executeOne]; break;
case 2: [self executeTwo]; break;
case 3: [self executeThree]; break;
}
One possible approach:
Let's assume you can piece together the (actually somewhat tedious) use of rangeOfString and rangeOfCharacter calls together and can write a method like this:
-(NSInteger)numberOfMatchesFoundInString:(NSString*)inputString;
which lets you pass in a string, and returns a 0,1,2... based on how many matches are found.
To use this convenient result in a highly readable way, you can use a switch statement.
NSInteger* matches = [self numberOfMatchesFoundInString:someString];
switch (matches) {
case 0:
//execute some code here for when no matches are found
break;
case 1:
//execute some different code when one match is found
break;
case 2:
//you get the idea
break;
default:
//some code to handle exceptions if the numberOfMatchesFoundInString method went horribly wrong
break;
Of course some people will tell you that this is functionally no different than calling
if (someCondition) {
//do some stuff
}
else if (someOtherCondition) {
//do some different stuff
}
etc...
but really, you can make either one work.
There are a few useful techniques you can use for string comparisons.
If you just need test if your string is one of a list of strings, use something like this:
NSArray *options = #[#"first", #"second", #"third"];
if ([options contains:inputString]) {
// TODO: Write true block
} else {
// TODO: Write else block
}
If you want to check if your string contains at least one character from a set, use NSString -rangeOfCharacterFromSet:.
Unfortunately, if you want to check if your string contains one or more strings, you have no choice but to write it out the long way. If you do it frequently enough, you may choose to write a class category.
- (BOOL)containsAtLeastOneSubstring:(NSArray *)substrings
{
for (NSString *aString in substrings) {
NSRange range = [self rangeOfString:aString];
if (range.location!=NSNotFound) {
return YES;
}
}
return NO;
}
-
Related
This question already has answers here:
Using an NSString in a switch statement
(9 answers)
Closed 9 years ago.
I want to implement a switchs/case where I can use a string to evaluate the switch case.
switch (tmp) {
case one:
NSLog(#"the string value of tmp is one");
break;
any of you knows how can I implement something like this?
I really appreciate your help
You can not use string in switch case statement, you can use only int or char data type.
But as i think your question is to make switch case more easy to understandable or readable.
So you can make enum for that, like:
typedef enum {
zero,//by default the value starts from zero.
one,
two
} NumCount;
At the point you have use it.
NumCount tmp = one;
switch (tmp) {
case one:
NSLog(#"the string value of tmp is one");
break;
}
I think you understand what i want to say. If you have any doubt please ask from me.
I have predefined enum for buttons IDs:
typedef enum
{
button1ID = 407,
button2ID = 999,
button3ID = 408,
button4ID = 409,
} TOP_MENU_BUTTON_TYPE;
I need to find out if the ID I recieve is defiened in the enum. How can I do that? Something like:
if(id in TOP_MENU_BUTTON_TYPE)
There is no way to dynamically iterate an enum. Enums are static feature, they don't exist during runtime. In runtime they are just plain integers (of some size) and values.
It's not possible with this requirement you stated in bounty:
In your answer do not use hard coded values of the enum, just its type.
The other answers show you pretty much all ways to do it statically.
If I understand your question clearly, then this would be helpful to you..
Instead of using enum alone, you should try that with struct and here it is an answer by #Richard will help you how to do that.
Change enum values at runtime?
https://stackoverflow.com/a/10305425/1083859
In the above link, he explains how to use a dynamic enum values with struct and also you can iterate the values to find out. I think you will get an idea.
You can simply do this:
int validValue = button1ID | button2ID | button3ID | button4ID;
if (validValue & id)
// Valid enum value
An enum is not an object, it's just an integer that the compiler understands at build time. Because of this, you would need to provide low level code to make your check.
If you aren't pre-defining the values of your enums, they will start at 0 and increase by one. This lets you compare a value to see if it's <= your last element.
try this method:
-(BOOL)isDefined:(TOP_MENU_BUTTON_TYPE)type{
BOOL isDefined;
switch (type) {
case button1ID:
case button2ID:
case button3ID:
case button4ID:
isDefined = TRUE;
break;
default:
isDefined = FALSE;
break;
}
return isDefined;
}
//(...)
TOP_MENU_BUTTON_TYPE test;
test = 407;
NSLog(#"is %d a TOP_MENU_BUTTON_TYPE? result: %d", test, [self isDefined:test]);
test = 2;
NSLog(#"is %d a TOP_MENU_BUTTON_TYPE? result: %d", test, [self isDefined:test]);
so:
if ([self isDefined:test]){
// OK, test is defined in TOP_MENU_BUTTON_TYPE
}
in .h
typedef enum
{
407,
999,
408,
409,
} TOP_MENU_BUTTON_TYPE;
#interface CheckoutController : UIViewController{
TOP_MENU_BUTTON_TYPE type;
}
In .m
switch (status) {
case 407:
//Your Task
break;
case 999:
//Your Task
break;
case 408:
//Your Task
break;
case 409:
//Your Task
break;
}
Answers about using switch or bunch of || in if are correct, but…
If you have big enums (enum with a lot of values) you can make this simplier. Also Cocoa uses this trick.
Your enum values must be incremented by one.
Then add to enum two additional values:
typedef enum {
buttonIDMin = 407, // Lowest value
button1ID = 407,
button2ID = 408, // Incremented by ONE
button3ID = 409,
button4ID = 410,
buttonIDMax = 410, // Highest value
} TOP_MENU_BUTTON_TYPE;
When you are comparing, you just need to do:
if (buttonID >= buttonIDMin && buttonID <= buttonIDMax) ...
I've got myself a piece of the iPhone SDK and been trying to make some simple apps. In this one, i want to compare the first character of self.label.string with the last one of ((UITextField *)sender).text. I decided to name them self.texty and self.input, respectively.
I would expect this if statement returning yes to me under certain circumstances, however I can't seem to get that done.
(in my case, my self.label.string was equal to 'hello!', while my self.input ended in an 'h'.)
self.input = [NSString stringWithFormat:#"%#", [((UITextField *)sender).text substringFromIndex:[((UITextField *)sender).text length]-1]];
self.texty = [NSString stringWithFormat:#"%#", [self.label.string substringToIndex:1]];
if (self.input == self.texty) {
return yes;
} else {
return no;
}
String comparison is not done with ==, but with one of the comparison methods of NSString.
For example:
if ([self.input compare:self.texty] == NSOrderedSame) {
if ([self.input isEqualToString:texty]) {
return yes;
} else {
return no;
}
EDIT:
Or a better version as the commenters noted:
return [self.input isEqualToString:texty];
If you're curious why the == operator doesn't work as expected, it's because you're actually comparing two scalar types (pointers to NSString objects) not the contents of the NSString objects themselves. As a result, it will return false unless the two compared NSStrings are actually the same instance in memory, regardless of the contents.
I have a rather simple question and forgive me if it is sacrilege to ask it haha.
I have 6 variables that I need to test if they are null or if their length is 0. So I figured that maybe I could use two switches, one for testing if it is string == [NSNull null] and one for testing string.length == 0. Instead of making a huge and complicated if.
A switch such as:
switch([NSNull null])
{
case string:
Do something
break;
case string2:
Do something else
break;
// etc...
}
and then another one such as:
switch( length==0) //I know length==0 doesn't work, but maybe you know an alternative
{
case string:
Do something
break;
case string2:
Do something else
break;
// etc...
}
Thank you for your help!
For your first switch statement, you can't an object within your switch brackets (an instance of NSNull is returned [NSNull null]). You must use primitives within the bracket only. Furthermore, your throught process is clearly flawed, as [NSNull null] will always return the same sort of object (an object that represents a null value), and therefore you have nothing to switch on, as opposed to switching on an integer, whereby your case statements could be for different integers.
For your second switch statement, you cannot (again) use objects for your cases (NSString is, of course, an object). The best thing to do here would be to use a series of if else clauses as follows:
if ([string length] == 0)
{
if ([string isEqualTo:#"firstStringToCheck"])
{
// Do something.
}
else if ([string isEqualTo:#"secondStringToCheck"])
{
// Do something else.
}
}
Notice that I also use the instance method named length in order to get the length of the string and check that it is 0. This seems to be what you were trying to do in your example, but also makes absolutely no sense to me. Why would you want to check strings with other strings when you know that if the string's length is 0 it couldn't possibly match any strings!
You're totally misunderstanding how the switch statement works. It's designed to test multiple possible variables for a set of possible values. Specifically to replace code like:
if (value == 0)
NSLog (#"zero");
else if (value == 1)
NSLog (#"one");
else if (value == 2)
NSLog (#"two");
else if (value == 3)
NSLog (#"three");
else if (value == 4)
NSLog (#"four");
else if (value == 5)
NSLog (#"five");
else
NSLog (#"Integer out of range");
with
switch (value)
{
case 0:
NSLog (#"zero");
break;
case 1:
NSLog (#"one");
break;
case 2:
NSLog (#"two");
break;
case 3:
NSLog (#"three");
break;
case 4:
NSLog (#"four");
break;
case 5:
NSLog (#"five");
default:
NSLog (#"Integer out of range");
break;
}
what you're currently doing will give you unexpected results. Use an if statement, or write a function to handle testing for null. See enter link description here, where I shamelessly cribbed these examples from for more information.
Could someone explain what is wrong with this "if statement"? I get:
"lvalue required as left operand of assignment".
This does not work:
if ([[prepDataArray objectAtIndex:iNDEX] boolValue] = YES) {
NSLog(#"HARD");
}
While this works:
diffQ = [[prepDataArray objectAtIndex:iNDEX] boolValue];
if (diffQ = YES) {
NSLog(#"HARD");
}
I do realize where the problem are and that the 'lvalue' indicate that i need to have something different on the left side but i do not grasp why and how to do what i want inside the 'if' statement as tried in the first example.
Would appreciate if someone nice could give me a hint :-)
if ([[prepDataArray objectAtIndex:iNDEX] boolValue] == YES) {
NSLog(#"HARD");
}
it's == not =
The first one doesn't work because you try to assign a BOOL (YES) to a message. The second one works because you try to assign a BOOL to diffQ. This is correct, but not the result you expect (comparing diffQ to YES)
Common programming error ;) I've done this a millions times
I completely agree with what #thomas said above, but let me add.
Don't compare a bool to YES. It's not that the if construct requires
if( some comparison statement ) {
....
}
That's not the case. The if construct has the following form:
if( a boolean value) {
...
}
It just happens that a comparison statement yields a boolean, so you put that in the if statement.
In your case, boolValue already gives you a bool. You don't need to compare that against YES or NO. That's like doing YES==YES or YES==NO and it's completely redundant.
Just do
if ([[prepDataArray objectAtIndex:iNDEX] boolValue]) {
NSLog(#"HARD");
}