Reputation: 7588
I have myDict in the format of:
{
data1 = {
key1 = abc
key2 = abc
key3 = abc
key4 = abc
},
data2 = {
key1 = abc
key2 = abc
key3 = abc
key4 = abc
}
..
}
I use the following code to sort myDict and get the the sorted data by keys.
sortedArr = [myDict keysSortedByValueUsingComparator:
^NSComparisonResult(NSDictionary* obj1, NSDictionary* obj2)
{
NSComparisonResult result = NSOrderedSame;
if(obj1[@"key1"] != nil && obj2[@"key1"]!=nil)
{
return [obj2[@"key1"] compare:obj1[@"key1"]];
}
else
return result;
}];
sortedArr:
(data1,data2,data3,...)
question is how do i sort myDict using 2 keys instead of one because I face an issue if key1 value are the same, then i want it to be sorted by key2.
Upvotes: 0
Views: 147
Reputation: 9935
You cannot insert nil into collections (dictionaries, arrays, index sets, etc).
You can, however, insert [NSNull null] into them as this is what they made it for
Below you can find the code which sorts the first level dictionaries by all keys within subDictinaries.
NSMutableDictionary *md = [NSMutableDictionary dictionary];
NSMutableDictionary *data1 = [NSMutableDictionary dictionary];
[data1 setObject:@"abc" forKey:@"key1"];
[data1 setObject:@"abc" forKey:@"key2"];
[data1 setObject:@"abc" forKey:@"key3"];
[data1 setObject:@"a" forKey:@"key4"];
NSMutableDictionary *data2 = [NSMutableDictionary dictionary];
[data2 setObject:@"abc" forKey:@"key1"];
[data2 setObject:@"abc" forKey:@"key2"];
[data2 setObject:@"abc" forKey:@"key3"];
[data2 setObject:@"b" forKey:@"key4"];
NSMutableDictionary *data3 = [NSMutableDictionary dictionary];
[data3 setObject:@"abc" forKey:@"key1"];
[data3 setObject:@"abc" forKey:@"key2"];
[data3 setObject:@"abc" forKey:@"key3"];
[data3 setObject:@"c" forKey:@"key4"];
[md setObject:data1 forKey:@"data1"];
[md setObject:data2 forKey:@"data2"];
[md setObject:data3 forKey:@"data3"];
NSArray *allKeys = @[@"key1", @"key2", @"key3", @"key4"];
NSArray *sortedData = [md keysSortedByValueUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
for (NSString *key in allKeys) {
if (obj1[key] != nil && obj2[key] != nil) { // Checking if both keys exist
NSComparisonResult result = [obj2[key] compare:obj1[key]];
if (result != NSOrderedSame) {
return result;
}
} else { // One of keys is missing
return NSOrderedSame;
}
}
return NSOrderedSame; // No keys
}];
NSLog(@"%@", sortedData);
Output:
( data3, data2, data1 )
Upvotes: 0
Reputation: 32066
You just need to account for the case for each key where the comparison returns NSOrderedSame
. You can iterate the keys like this:
NSArray *allKeys = @[@"key1", @"key2", @"key3", ...];
for (NSString *aKey in allKeys)
{
if(obj1[aKey] != nil && obj2[aKey] != nil)
{
NSComparisonResult result = [obj2[aKey] compare:obj1[aKey]];
if (result != NSOrderedSame) return result;
}
}
return NSOrderedSame;
This answer is substantially different from my original answer, all credit to Larme for this solution
Upvotes: 3