I have and array of custom objects of Person Class
Person : NSObject{
NSString *firstName;
NSString *lastName;
NSString *age;
}
NSMutableArray
I have created a small library called Linq-to-ObjectiveC which provides a number of methods which make is easier to query arrays. In order to perform the group operation you require you can simply do the following:
NSDictionary* groupedByName = [personsArray groupBy:^id(id person) {
return [person firstName];
}];
This would return a dictionary where the keys are the distinct first names, and each value is an array of 'person' objects that have the given first name.
You can try this is custom object sorting for an array
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"Firstname" ascending:NO selector:@selector(compare:)];
[Array sortUsingDescriptors:[NSArray arrayWithObjects:sortDescriptor, nil]];
Checkout this answers it is very similar to what you want
https://stackoverflow.com/a/15375756/1190861
The code in your case will be as the following:
NSMutableDictionary *result = [NSMutableDictionary new];
NSArray *distinctNames;
distinctNames = [personsArray valueForKeyPath:@"@distinctUnionOfObjects.firstName"];
for (NSString *name in distinctNames) {
NSPredicate predicate = [NSPredicate predicateWithFormat:@"firstName = %@", name];
NSArray *persons = [personsArray filteredArrayUsingPredicate:predicate];
[result setObject:persons forKey:name];
}
NSLog(@"%@", result);
- (NSDictionary *)groupObjectsInArray:(NSArray *)array byKey:(id <NSCopying> (^)(id item))keyForItemBlock
{
NSMutableDictionary *groupedItems = [NSMutableDictionary new];
for (id item in array)
{
id <NSCopying> key = keyForItemBlock(item);
NSParameterAssert(key);
NSMutableArray *arrayForKey = groupedItems[key];
if (arrayForKey == nil)
{
arrayForKey = [NSMutableArray new];
groupedItems[key] = arrayForKey;
}
[arrayForKey addObject:item];
}
return groupedItems;
}
A Drop in code to help you doing it,
-(NSMutableArray *)sortArray:(NSArray *)arrayTosort withKey:(NSString *)key ascending:(BOOL)_ascending
{
NSSortDescriptor *sortDescriptor;
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:key
ascending:_ascending] ;
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
return [[arrayTosort sortedArrayUsingDescriptors:sortDescriptors] mutableCopy];
}
here key is key
or keypath
.
There isn't a built in group by method in NSArray
. Your example implementation could be added as a category.
Unfortunately, the @distinctUnionOfObjects
operation will only return the strings of the firstName property: John, David. It won't do a group by
operation, nor is there such an operation.
Collection Operations