Vignesh Babu
Vignesh Babu

Reputation: 690

Case Insensitive Search in NSMutableDictionary

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.

Upvotes: 6

Views: 3206

Answers (4)

unsynchronized
unsynchronized

Reputation: 4938

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.

Upvotes: 6

Deepak Danduprolu
Deepak Danduprolu

Reputation: 44633

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.

Upvotes: 2

Tom Jefferys
Tom Jefferys

Reputation: 13310

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

Upvotes: 1

csano
csano

Reputation: 13686

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.

Upvotes: 4

Related Questions