0

Rather than a long if statement, what is a more compact and readable way to verify if a string is contained in a collection of possible values? In other words, check if a value is within a domain?

I want to do something like this…

NSArray* domain = [NSArray arrayWithObjects:@"dog", @"cat", @"bird", nil];
BOOL valueFoundInDomain = [domain containsObject:@"elephant"];

But I'm concerned about equality checking with NSString. I want to check the value of the text, not object identity.

The documentation for NSArray says the containsObject method uses the isEqual method. But I cannot find in the documentation for NSString an explanation for its implementation of isEqual. The presence of the isEqualToString method suggests that isEqual may be doing something else. If that something else involves interning of string objects, then experimenting myself may give misleading results, so I'd like a documented answer.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • 2
    See [NSString: isEqual vs. isEqualToString](http://stackoverflow.com/q/1292862/3476191) – NobodyNada May 09 '14 at 20:50
  • You could do your test by building some string using `NSMutableString`. Then you can be assured that identity checks won't be involved. – rmaddy May 09 '14 at 21:15

3 Answers3

0

I never use -isEqualToString:, only -isEqual: and it just works as it should! (I do this for years.)

NSString is implementing -isEqual: and it returns YES if the other object is a string and it has the same contents.

In Apples Objective-C documentation, methods that are overridden from a baseclass are often not explicitely documented. But -isEqual: is one of the few methods that is implemented in all foundation classes where it makes sense.

Michael
  • 6,451
  • 5
  • 31
  • 53
  • FYI - Using `isEqualToString:` is more efficient if you know that both sides really are `NSString` objects. This should be considered in loops and other places where you do a lot of string comparisons. – rmaddy May 09 '14 at 21:14
  • i often just don't want the app to crash if the other object is not a string or if it is `[NSNull null]`. Calling `-isEqual:` also saves 8 bytes in the source file ;) – Michael May 09 '14 at 21:17
  • As I said, use `isEqualToString:` if you know both side are `NSSString`. Your `NSNull` example wouldn't apply obviously. – rmaddy May 09 '14 at 21:19
  • maybe you're right. it's just that 99% of the source code that I see has much worse performance problems than that, so that this particular issue wouldn't make a difference. Just a for-loop like `for(int i=0; i<[list count]; i++)` is inefficient compared to `int list_count = [list count]; for(int i=0; i – Michael May 09 '14 at 21:25
  • 1
    Follow [the link in the comment](http://stackoverflow.com/q/1292862/3476191) posted on Question by NobodyNada. Turns out there is **likely *no* significant performance difference** between `isEqual` and `isEqualToString` for NSString despite the claim by Apple doc. – Basil Bourque May 09 '14 at 22:06
0

The isEqual method does an additional type check to ensure you are comparing two objects of the same class.

IsEqualToString assumes you are sending a string and will crash if you send a nil or object of another type.

Your code looks good for its use case.

Venkat S. Rao
  • 1,110
  • 3
  • 13
  • 29
0

Lets Try Using This

NSArray* domain = [NSArray arrayWithObjects:@"dog", @"cat", @"bird", nil];
NSIndexSet *indexes = [domain indexesOfObjectsWithOptions:NSEnumerationConcurrent passingTest:^BOOL(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    return [obj isEqualToString:@"elephant"];
}];
// Where indexes contains matched indexes of array elements 

Here isqualToString: Returns a Boolean value that indicates whether a given string is equal to the receiver using a literal Unicode-based comparison.isEquealTo: Returns a Boolean value that indicates whether the receiver and a given object are equal. When you know both objects are strings, isEqualToString: is a faster way to check equality than isEqual: