40

I have a NSMutableArray which contains a few NSString objects. How can I test if the array contains a particular string literal?

I tried [array containsObject:@"teststring"] but that doesn't work.

5 Answers 5

87

What you're doing should work fine. For example

NSArray *a = [NSArray arrayWithObjects:@"Foo", @"Bar", @"Baz", nil];
NSLog(@"At index %i", [a indexOfObject:@"Bar"]);

Correctly logs "At index 1" for me. Two possible foibles:

  1. indexOfObject sends isEqual messages to do the comparison - you've not replaced this method in a category?
  2. Make sure you're testing against NSNotFound for failure to locate, and not (say) 0.
Sign up to request clarification or add additional context in comments.

5 Comments

It will not work in certain cases because it checks reference.
@Stoto It does not check references. It uses -isEqual: as the answer describes.
LOL! @Stoto it sounds like you've been reading this thread devforums.apple.com/thread/168948?start=0&tstart=0
Yes, i did :) I am sure it checks reference, but due to compiler optimization two @"Bar" string constants are basically one String (pointers pointing to the same data)
For the record, I tested this option and it works perfectly. Apple's reference at developer.apple.com/library/ios/#documentation/Cocoa/Reference/… explicitly states that isEqual: is used for comparisons. On NSString objects, isEqual: tests the contents of the strings.
78
[array indexOfObject:object] != NSNotFound

Comments

8

Comparing against string literals only works in code examples. In the real world you often need to compare against NSString* instances in e.g. an array, in which case containsObject fails because it compares against the object, not the value.

You could add a category to your implementation which extends NS(Mutable)Array with a method to check wether it contains the string (or whatever other type you need to compare against);

@implementation NSMutableArray (ContainsString)
-(BOOL) containsString:(NSString*)string
{
  for (NSString* str in self) {
    if ([str isEqualToString:string])
      return YES;
  }
  return NO; 
}
@end

2 Comments

I don't think this is true. Apple's docs for containsObject and indexOfObject both say each element is sent an isEqual: message, so it should work even when two different NSString objects contain the same character content.
that is only true if both objects are NSString
6

You may also use a predicate:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF IN %@", theArray];
BOOL result = [predicate evaluateWithObject:theString];

Comments

5

for every object

[(NSString *) [array objectAtIndex:i] isEqualToString:@"teststring"];

7 Comments

I downvoted because it's not the right answer. You don't need to manually iterate over the array, because indexOfObject works fine. This answer will always be slower (sending many messages, no access to internal representations), and far more cumbersome. I only downvote answers when I have myself posted another answer when it's unambiguously wrong.
I think this is correct if the strings are not static. Equality works for static strings, but not for dynamically allocated ones.
It may not be the accepted answered, but its still a valid answer. I dont think down voting it was appropriate
The accepted answer is wrong because First of all it checks the reference which can be the same if you have string constant like in the example, but will not work if the same string will be created dynamically (coming from file, web, ...) Second, there is a containsObject: method for the same thing, so you shouldn't use indexOfObject: for this. Therefore this is the correct answer.
it's simply wrong to use indexOfObject, this is the correct answer.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.