HI, I have a NSMutableDicitionary contains both lowercase and uppercase keys. So currently i don't know how to find the key in the dictionary irrespective key using objective c.
4 Answers
Categories to the rescue. Ok, so it's an old post...
@interface NSDictionary (caseINsensitive)
-(id) objectForCaseInsensitiveKey:(id)aKey;
@end
@interface NSMutableDictionary (caseINsensitive)
-(void) setObject:(id) obj forCaseInsensitiveKey:(id)aKey ;
@end
@implementation NSDictionary (caseINsensitive)
-(id) objectForCaseInsensitiveKey:(id)aKey {
for (NSString *key in self.allKeys) {
if ([key compare:aKey options:NSCaseInsensitiveSearch] == NSOrderedSame) {
return [self objectForKey:key];
}
}
return nil;
}
@end
@implementation NSMutableDictionary (caseINsensitive)
-(void) setObject:(id) obj forCaseInsensitiveKey:(id)aKey {
for (NSString *key in self.allKeys) {
if ([key compare:aKey options:NSCaseInsensitiveSearch] == NSOrderedSame) {
[self setObject:obj forKey:key];
return;
}
}
[self setObject:obj forKey:aKey];
}
@end
enjoy.

- 4,828
- 2
- 31
- 43
-
3What is bad about this way, is that you are eliminating the main advantage of dictionary - _fast_ lookup. Search complexity increases from `O(log(N)))` to `O(N)`. – ivanzoid Jan 16 '13 at 06:45
Do you have control over the creation of the keys? If you do, I'd just force the keys to either lower or upper case when you're creating them. This way when you need to look up something, you don't have to worry about mixed case keys.

- 13,266
- 2
- 28
- 45
-
This is, by far, the easiest solution. Force the keys to upper or lower case on insertion and do the same on lookup. If you have overlap ("steve" and "Steve" are both valid keys), then this won't work. – bbum May 26 '11 at 08:14
-
I didn't have control over creation of Key. The problem is combination of upper and lower case letter. I didn't have any idea to solve it.Help me in this issue – Vignesh Babu May 26 '11 at 12:05
-
Can you give me a little bit more context? Where is this dictionary coming from? Do you have any ideas about the keys that the dictionary contains? – csano May 27 '11 at 02:21
-
For instance, some Dictionaries I'm working with are holding JSON data where the key is formulated from a REST response. So, this isn't an answer for every situation, although it is a good idea! – Brett Mar 06 '13 at 17:58
You can do this to get the object as an alternative to subclassing.
__block id object;
[dictionary enumerateKeysAndObjectsWithOptions:NSEnumerationConcurrent
UsingBlock:^(id key, id obj, BOOL *stop){
if ( [key isKindOfClass:[NSString class]] ) {
if ( [(NSString*)key caseInsensitiveCompare:aString] == NSOrderedSame ) {
object = obj; // retain if wish to.
*stop = YES;
}
}
}];
You can use a #define
shorthand if you find yourself doing this a lot in your code.

- 44,595
- 12
- 101
- 105
-
A perfectly good solution as long as your dictionaries are relatively small and/or you aren't looking up keys **that** often. Never discount a seemingly inefficient solution until you have performance data indicating that it is a problem! – bbum May 26 '11 at 08:15
Don't think there's any easy way. Your best option might be to create a subclass of NSMutableDictionary
, and override the objectForKey
and setObject:ForKey
methoods. Then in your overridden methods ensure that all keys are converted to lowercase (or uppercase), before passing them up to the superclass methdods.
Something along the lines of the following should work:
@Interface CaseInsensitveMutableDictionary : MutableDictionary {}
@end
@implementation CaseInsensitveMutableDictionary
- (void) setObject: (id) anObject forKey: (id) aKey {
[super setObject:anObject forKey:[skey lowercaseString]];
}
- (id) objectForKey: (id) aKey {
return [super objectForKey: [aKey lowercaseString]];
}
@end

- 13,090
- 2
- 35
- 36
-
Good idea, but you can't subclass *Dictionary that way; you'd have to implement the primitive methods in the class cluster. – bbum May 26 '11 at 08:13
-
Hi, thanks for your feedback. If i inherit the nsmutabledictionary it will not violate rules of apple right? – Vignesh Babu May 26 '11 at 12:06