NSDictionary & NSMutableDictionary Tutorial

In this Tutorial, I have covered the most useful methods of NSDictionary and NSMutableDictionary with examples.
Below is the list of examples
1 Difference between NSDictionary and NSMutableDictionary
2) How to create NSDictionary with key and values
3) Convert NSDictionary to NSMutableDictionary
4) Size of a Dictionary
5) Adding and Removing entries to NSMutableDictionary
6) Accessing NSDictionary Key and values
7) Enumerating Dictionaries
8) Comparing Dictionaries
9) Sort Dictionaries

 

1) Difference between NSDictionary and NSMutableDictionary

In Objective-C , NSDictionary is the most common used class. In NSDictionary, Entries are stored in the form of key value pairs. A Dictionary can hold NSNumber, NSString, NSArray, ..etc and their mutable objects.

Below is the simple Dictionary in JSON format.

{
    "name": "Hayagreeva",  //String
    "age": 3,        //Number
    "date": "2008-02-16T10:06:00Z"  //Date
}

A bit complex Dictionary is below. Dictionary contains an array,and that array contains dictionary.

{
    "name": "Hayagreeva", //String
    "age": 3,  //Number
    "subjects": {  //Array
        "rhymes": {   //Dictionary 1
            "test1": 10,
            "test2": 20,
            "test3": 30
        },
        "games": {  //Dictionary 2
            "test1": 40,
            "test2": 50,
            "test3": 60
        },
        "crayoning": { //Dictionary 3
            "test1": 70,
            "test2": 80,
            "test3": 90
        }
    },
    "date": "2008-02-16T10:06:00Z"  //Date
}

Main Difference is:
NSMutableDictionary is derived from NSDictionary, it has all the methods of NSDictionary.
NSMutableDictionary is mutable( can be modified) but NSDictionary is immutable (can not be modified).

 

2) How to create NSDictionary with key and values

To create a dictionary you can use static methods, or initialization methods.

Static methods:
+ (instancetype)dictionary;
+ (instancetype)dictionaryWithObject:(id)object forKey:(id <NSCopying>)key;
+ (instancetype)dictionaryWithObjectsAndKeys:(id)firstObject, ... nil;
+ (instancetype)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys;
+ (instancetype)dictionaryWithDictionary:(NSDictionary *)dict;

Init Methods:
- (instancetype)init;
- (instancetype)initWithObjectsAndKeys:(id)firstObject, ... nil;
- (instancetype)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys;
- (instancetype)initWithDictionary:(NSDictionary *)otherDictionary;

how to create a dictionary example:

    NSString * key1 =@"name";
    NSString * obj1 =@"Hayagreeva";
    NSString * key2 =@"age";
    NSNumber * obj2 =[NSNumber numberWithInt:3];

    //1.Empty dictionary. @{} dictionary representation and it is not for NSMuableDictionary
    NSDictionary * dict1 =[NSDictionary dictionary];
    NSDictionary * dict2 =[[NSDictionary alloc] init];
    NSDictionary * dict3 = @{};

    //2.Dictionary with Single Object and Key
    NSDictionary * dict4 =[NSDictionary dictionaryWithObject:obj1 forKey:key1];
    NSDictionary * dict5 =@{key1:obj1};

    //3.Dictionary with Multiple Object and Keys
    //Objects and keys are sequentially terminated with nil
    NSDictionary * dict6 = [NSDictionary
                            dictionaryWithObjectsAndKeys:obj1,key1,obj2,key2,nil];

    NSDictionary * dict7 =[[NSDictionary alloc]
                            initWithObjectsAndKeys:obj1,key1,obj2,key2,nil] ;

    //3.Dictionary with Multiple Object and Keys
    NSDictionary *dict8 =[NSDictionary
                          dictionaryWithObjects:@[obj1,obj2]
                          forKeys:@[key1,key2]];
    NSDictionary *dict9 =[[NSDictionary alloc]
                          initWithObjects:@[obj1,obj2]
                          forKeys:@[key1,key2]];
    NSDictionary * dict10 =@{key1:obj1,key2:obj2};

    //@[obj1,obj2] is the array representation.  dict6,dict7,dict8 are same.
    NSDictionary *dict11 =[[NSDictionary alloc]
                          initWithObjects:[NSArray arrayWithObjects:obj1,obj2,nil]
                          forKeys:[NSArray arrayWithObjects:key1,key2,nil]];

    //4.Dictionary with another Dictionary
    //@[obj1,obj2] is the array representation.  dict6,dict7,dict8 are same.
    NSDictionary *dict12=[NSDictionary dictionaryWithDictionary:dict8];
    NSDictionary *dict13=[[NSDictionary alloc] initWithDictionary:dict8];

Note: You can use same methods to create NSMutableDictionary. @{} representation is only for NSDictionary.

 

3) Convert NSDictionary to NSMutableDictionary

NSDictionary is mutable, So if you want to make any modifications to that you need to convert it as NSMutableDictionary and make changes.
To convert NSDictionary to NSMutableDictionary, you can use the method mutableCopy
Example:

     NSDictionary * dict = [NSDictionary
                                  dictionaryWithObjects:@[@"Ravi",@"33",@"India",@"India"]
                                  forKeys:@[@"name",@"age",@"location",@"country"]];
    //You can not do this
    //[dict setValue:@"XXX" forKey:@"YYY"];

    NSDictionary * mutable =[dict mutableCopy];
    //You set value
    [mutable setValue:@"XXX" forKey:@"YYY"];

 

4) Size of a Dictionary

You can use count properity to get the size of a dictionary. Below is the example.

    NSDictionary *dict =[[NSDictionary alloc] initWithObjects:@[@"Ravi",@"33"] forKeys:@[@"name",@"age"]];
    NSLog(@"Dictionary Size =%d",dict.count);

 

5) Adding and Removing entries to NSMutableDictionary

5.1) Adding Entries
You can add entries to NSMutableDictionary using the following methods:

- (void)setObject:(id)anObject forKey:(id <NSCopying>)aKey;
- (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)key NS_AVAILABLE(10_8, 6_0);
- (void)addEntriesFromDictionary:(NSDictionary *)otherDictionary;
- (void)setValue:(id)value forKey:(NSString *)key;

Example:

    NSMutableDictionary *dict =[[NSMutableDictionary alloc] init];
    //1. using setValue
    [dict setValue:@"Hayagreeva" forKey:@"name"];

    //2. using setObject
    [dict setObject:[NSNumber numberWithInt:3] forKey:@"age"];
    [dict setObject:[NSDate date] forKey:@"date"];

    //3 adding entries using subscript
    dict[@"city"]=@"Hyderabad";

    //3). Adding Objects from Another Dictionary
    [dict addEntriesFromDictionary:[NSMutableDictionary
                                    dictionaryWithObjectsAndKeys:
                                    @"India",@"location", nil]];

5.1) Removing Entries
You can remove entries from NSMutableDictionary using the following methods.

- (void)removeObjectForKey:(id)aKey;
- (void)removeObjectsForKeys:(NSArray *)keyArray;
- (void)removeAllObjects;

Example:

    NSMutableDictionary * dict = [NSMutableDictionary
                                  dictionaryWithObjects:@[@"Ravi",@"33",@"India",@"India"]
                                  forKeys:@[@"name",@"age",@"location",@"country"]];

    //1. Remove entry with given key
    [dict removeObjectForKey:@"city"];

    NSLog(@"Dict =%@",dict);

    //2. Remove Entries with given keys.
    [dict removeObjectsForKeys:@[@"location",@"age"]];

    NSLog(@"Dict =%@",dict);

    //3. Remove all the entries
    [dict removeAllObjects];
    NSLog(@"Dict =%@",dict);

 

6) Accessing NSDictionary Key and values

5.1) Access Values using with Given key
Values are accessed using array subscript or objectForKey method. List of methods for accessing keys and values.

- (id)objectForKey:(id)aKey;
- (id)valueForKey:(NSString *)key;

//to access all keys or objects
- (NSArray *)allValues;
- (NSArray *)allKeys;
- (NSArray *)allKeysForObject:(id)anObject;

Example:

 NSMutableDictionary * dict = [NSMutableDictionary
                                  dictionaryWithObjects:@[@"Ravi",@"33",@"India",@"India"]
                                  forKeys:@[@"name",@"age",@"location",@"country"]];
    //1.using objectForKey
    NSString * name = [dict objectForKey:@"name"];

    //2. using array subscript
    NSString * location = dict[@"location"];

    //3. using valueForKey
    NSString * age =[dict valueForKey:@"age"];

    //4. Access all the values  as array
    NSArray * values =[dict allValues];
    for (id value in values) {
        NSLog(@"value =%@",value);
    }

    //5. Access all the keys
    NSArray * keys =[dict allKeys];

    for(NSString * key in keys)
    {
        NSString * value =[dict objectForKey:key];
        NSLog(@"key=%@, value=%@",key, value);
    }

    //6. Access keys with given object
    NSArray * skeys =[dict allKeysForObject:@"India"];
    for (NSString * key in skeys) {
        NSLog(@"key =%@",key);
    }

 

7) Enumerating Dictionaries

To enumerate Dictionaries, you can use the following the methods:

- (NSEnumerator *)keyEnumerator;
- (NSEnumerator *)objectEnumerator;
- (void)enumerateKeysAndObjectsUsingBlock:(void (^)(id key, id obj, BOOL *stop))block NS_AVAILABLE(10_6, 4_0);
- (void)enumerateKeysAndObjectsWithOptions:(NSEnumerationOptions)opts usingBlock:(void (^)(id key, id obj, BOOL *stop))block NS_AVAILABLE(10_6, 4_0);

Example:

    NSMutableDictionary * dict = [NSMutableDictionary
                                   dictionaryWithObjects:@[@"33",@"India",@"India",@"Ravi"]
                                   forKeys:@[@"age",@"location",@"country",@"name"]];

    //Enumerator using keys
    NSEnumerator *kEnumerator = [dict keyEnumerator];
    id key=nil;
    while(key =[kEnumerator nextObject])
    {
        NSLog(@"Key =%@",key);
    }

    //Enumerator using values
    NSEnumerator *oEnumerator = [dict objectEnumerator];
    id value=nil;
    while(value =[oEnumerator nextObject])
    {
        NSLog(@"Value =%@",value);
    }

    //Enumerate using code block
    [dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop)
    {
        NSLog(@"%@:%@",key,obj);
    }];

 

8) Comparing Dictionaries

isEqualToDictionary method is used to compare dictionaries. It returns YES, if two dictionaries
are equal.
Example:

    NSMutableDictionary * dict1 = [NSMutableDictionary
                                  dictionaryWithObjects:@[@"Ravi",@"33",@"India",@"India"]
                                  forKeys:@[@"name",@"age",@"location",@"country"]];
    NSMutableDictionary * dict2 = [NSMutableDictionary
                                   dictionaryWithObjects:@[@"33",@"India",@"India",@"Ravi"]
                                   forKeys:@[@"age",@"location",@"country",@"name"]];

    NSMutableDictionary * dict3 = [NSMutableDictionary
                                   dictionaryWithObjects:@[@"Hayagreeva",@"2",@"India",@"India"]
                                   forKeys:@[@"name",@"age",@"location",@"country"]];
    if([dict1 isEqualToDictionary:dict2])
    {
        NSLog(@" dict 1 and dict 2 are equal");
    }
    if(![dict1 isEqualToDictionary:dict3])
    {
        NSLog(@" dict 1 and dict 3 are not equal");
    }

 

9) Sort Dictionaries

We can sort the dictionaries using the following methods.

- (NSArray *)keysSortedByValueUsingSelector:(SEL)comparator;
- (NSArray *)keysSortedByValueUsingComparator:(NSComparator)cmptr NS_AVAILABLE(10_6, 4_0);
- (NSArray *)keysSortedByValueWithOptions:(NSSortOptions)opts usingComparator:(NSComparator)cmptr NS_AVAILABLE(10_6, 4_0);

Sort NSDictionary example:

    NSMutableDictionary * services = [[NSMutableDictionary alloc] init];
    [services setObject:@"Mail" forKey:@"Yahoo"];
    [services setObject:@"Windows" forKey:@"Microsoft"];
    [services setObject:@"Social" forKey:@"Facebook"];
    [services setObject:@"Search" forKey:@"Google"];

    //sort by values
    NSArray * keys = [services
                      keysSortedByValueUsingComparator:
                      ^NSComparisonResult(id obj1, id obj2) {

                          //return [obj2 compare:obj1]; //descending
                          return [obj1 compare:obj2]; //ascending
                      }];
    for(NSString *key in keys)
    {
        NSLog(@"%@:%@",key,[services objectForKey:key]);
    }

    //Sort using Default comparator
    NSArray * keys2 = [services keysSortedByValueUsingSelector:@selector(compare:)];
    for(NSString *key in keys2)
    {
        NSLog(@"%@:%@",key,[services objectForKey:key]);
    }

If you want to use custom selector method with keysSortedByValueUsingSelector , you need to add that method in NSString using Categories. Below is the code.

@implementation NSString (Sort)
//compare starts from second character.ignore first character
- (NSComparisonResult)customeCompare:(NSString *)string
{
    NSString * str1 =[self substringFromIndex:1];
    NSString * str2 = [string substringFromIndex:1];
    return [str1 compare:str2];
}

Reference: Apple Documenation


I am a Developer. My motto: "Language is not a barrier" http://hayageek.com
All posts by Ravishanker Kusuma