I want to know how to invert a NSDictionary.
I've seen some crazy code like
NSDictionary *dict = ...;
NSDictionary *swapped = [NSDictionary dictionaryWithObjects:dict.allKeys forKeys:dict.allValues];
which is according to documentation not safe at all since the order of allValues
and allKeys
is not guaranteed.
You can swap keys and values in a dictionary with dictionary comprehensions and the items() method.
An NSDictionary will retain it's objects, and copy it's keys. Here are some effects this has had on code I've worked on. Sometimes you get the same object you put in, sometimes not. Immutable objects are optimized to return themselves as a copy .
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).
You have to convert NSDictionary to NSMutableDictionary . You have to user NSMutableDictionary in place of the NSDictionary . After that you can able to change value in NSMutableDictionary . Save this answer.
NSDictionary *dict = ...;
NSMutableDictionary *swapped = [NSMutableDictionary new];
[dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
swapped[value] = key;
}];
Note that the values should also conform to the NSCopying
protocol.
You're right, that code is crazy, but there are two ways to get an array of the values in the order given by an array of keys:
NSArray * keys = [dict allKeys];
NSArray * vals = [dict objectsForKeys:keys notFoundMarker:nil];
NSDictionary * inverseDict = [NSDictionary dictionaryWithObjects:keys
forKeys:vals];
Or
NSUInteger count = [dict count];
id keys[count];
id vals[count];
[dict getObjects:vals andKeys:keys];
NSDictionary * inverseDict = [NSDictionary dictionaryWithObjects:keys
forKeys:vals
count:count];
The former is obviously a lot nicer. As noted in hfossli's answer, the objects that were values in the original dictionary must conform to NSCopying
in order to be used as keys in the inversion.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With