Split an NSArray in smaller key value coded arrays using a common key-value pair between objects
arrays, objective-c, sorting, split
Solution
NSMutableDictionary* result = [NSMutableDictionary dictionary];
NSArray* ids = [array valueWithKey:@"id"];
NSSet* uniqueIDs = [NSSet setWithArray:ids];
for (NSNumber* anID in uniqueIDs)
{
NSPredicate* pred = [NSPredicate predicateWithFormat:@"id == %@", anID];
NSArray* dictsForID = [array filteredArrayUsingPredicate:pred];
[result setObject:dictsForID forKey:anID];
}
If there are lots of IDs, you may be able to speed this up a bit by building a predicate with a variable reference outside of the loop and then just substituting the variable in to produce the id-specific predicate for each pass through the loop.
By the way, in your question, the result "field" is still an array for some reason. I don't think it needs to be.
Updated to make just one pass:
NSMutableDictionary* result = [NSMutableDictionary dictionary];
for (NSDictionary* dict in array)
{
NSNumber* anID = [dict objectForKey:@"id"];
NSMutableArray* resultsForID = [result objectForKey:anID];
if (!resultsForID)
{
resultsForID = [NSMutableArray array];
[result setObject:resultsForID forKey:anID];
}
[resultsForID addObject:dict];
}
Problem
I'm trying to find a good solution to split an array of dictionaries in a smaller dictionaries keyed by a common value between them. Here is an example i JSON, I start from this: ``` { "field": [ { "id": 6, "name": "Andrea" }, { "id": 67, "name": "Francesco" }, { "id": 8, "name": "Maria" }, { "id": 6, "name": "Paolo" }, { "id": 67, "name": "Sara" } ] } ``` I'd like to get a result like: ``` { "field": [ { "6": [ { "name": "Andrea", "id": 6 }, { "name": "Paolo", "id": 6 } ], "67": [ { "name": "Sara", "id": 67 }, { "name": "Francesco", "id": 67 } ], "8": [ { "name": "Maria", "id": 8 } ] } ] } ``` I managed using this code, it works, but I'm wondering if exist something more correct and fast: ``` NSArray * array = ...; NSSortDescriptor *sorter1=[[NSSortDescriptor alloc]initWithKey:@"id" ascending:YES selector:@selector(compare:)]; NSSortDescriptor *sorter2=[[NSSortDescriptor alloc]initWithKey:@"name" ascending:YES selector:@selector(caseInsensitiveCompare:)]; NSArray *sortDescriptors=[NSArray arrayWithObjects:sorter1,sorter2,nil]; array = [array sortedArrayUsingDescriptors:sortDescriptors]; //////////////////////////////SPLITTER NSMutableArray * subcategorySplittedArray = [[NSMutableArray alloc]initWithCapacity:30]; NSNumber * lastID=[[array objectAtIndex:0]objectForKey:@"id"]; NSMutableArray * shopArray = [[NSMutableArray alloc]initWithCapacity:100]; NSMutableDictionary * catDict = nil; for (NSDictionary * dict in array) { NSNumber * catID = [dict objectForKey:@"id"]; if ([lastID isEqualToNumber:catID]) { [shopArray addObject:dict]; } else { catDict = [[NSMutableDictionary alloc]init ]; [catDict setObject:[shopArray copy] forKey:lastID]; [subcategorySplittedArray addObject:catDict]; [shopArray removeAllObjects]; [shopArray addObject:dict]; lastID = catID; } } catDict = [[NSMutableDictionary alloc]init ]; [catDict setObject:[shopArray copy] forKey:lastID]; [subcategorySplittedArray addObject:catDict]; //////////////////////////////////// return subcategorySplittedArray; } ```