ammar shahid
ammar shahid

Reputation: 411

Using NSPredicate to filter a value in NSDictionary and return the keys array

I've a dictionary with a string value and an int key.

i.e.

{1,abc}

{2,bcd}

{3,cde}

I'm filtering it using NSPredicate as follows

NSMutableDictionary *tableDataSearch;
    NSArray *searchResults;

NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"self contains[cd] %@", searchText];

searchResults = [[tableDataSearch allValues] filteredArrayUsingPredicate:resultPredicate];

it is returning me the array of values which contain the specific word. I want all keys to be returned in the array and search in values like it is searching right now. any help ?

Upvotes: 0

Views: 3048

Answers (2)

johnpatrickmorgan
johnpatrickmorgan

Reputation: 2372

The following code filters an NSDictionary based on a substring search on its values:

NSDictionary *data = @{@1 : @"abc",
                       @2 : @"bcd",
                       @3 : @"def"};

NSString *searchText = @"bc";

NSMutableDictionary *filteredData = [NSMutableDictionary new];

[data enumerateKeysAndObjectsUsingBlock:^(id key, NSString *obj, BOOL *stop) {
    NSRange range = [obj rangeOfString:searchText
                                options:NSCaseInsensitiveSearch | NSDiacriticInsensitiveSearch];
    if (range.location != NSNotFound)
    {
        [filteredData setObject:obj forKey:key];
    }
}];
NSArray *keys = [filteredData allKeys];

If this feels a bit cumbersome, BlocksKit provides some useful extensions to NSDictionary:

NSDictionary *filteredData = [data bk_select:^BOOL(id key, NSString *obj) {
    NSRange range = [obj rangeOfString:searchText
                               options:NSCaseInsensitiveSearch | NSDiacriticInsensitiveSearch];
    return range.location != NSNotFound;
}];

And if you prefer to use NSPredicate, you can replace range.location != NSNotFound with:

[resultPredicate evaluateWithObject:obj];

Upvotes: 1

Idali
Idali

Reputation: 1023

suppose you have an array of dictionaries myArrayOfDict. and dictionary have differentes keys. this will with gives you all dictionnary where any value contains your string:

NSMutableArray* myArrayOfDict = [@[@{@"key1":@"value1"} , @{@"key2": @"value2"}]mutableCopy];
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"ANY SELF.@allValues contains[cd] %@", @"lue1"];

NSArray *searchResults = [myArrayOfDict filteredArrayUsingPredicate:resultPredicate]; // will get the 2nd diction

Upvotes: 3

Related Questions