Grouping custom objects in Objective-C

I have an array of custom objects of class Person

Person : NSObject{ NSString *firstName; NSString *lastName; NSString *age; } NSMutableArray *personsArray = [NSMutableArray array]; Person *personObj1 = [[[Person alloc] init] autorelease]; personObj1.firstName = @"John"; personObj1.lastName = @"Smith"; personObj1.age = @"25"; [personsArray addObject: personObj1]; Person *personObj2 = [[[Person alloc] init] autorelease]; personObj2.firstName = @"John"; personObj2.lastName = @"Paul"; personObj2.age = @"26"; [personsArray addObject: personObj2]; Person *personObj3 = [[[Person alloc] init] autorelease]; personObj3.firstName = @"David"; personObj3.lastName = @"Antony"; personObj3.age = @"30"; [personsArray addObject: personObj3]; 

Now personArray contains 3 objects of Person objects.

Is it possible to group objects by an attribute of type age or firstName?

Expected Result

 NSDictionary { "John" = >{ personObj1, //(Its because personObj1 firstName is John ) personObj2 //(Its because personObj2 firstName is John ) }, "David" = >{ personObj3, //(Its because personObj3 firstName is David ) }, } 

I know that I can get this result by creating an NSDictionary and then Iterate through personArray and then checking every first

 NSMutableDictionary *myDict = [NSMutableDictionary dictionary]; for (Person *person in personsArray){ if([myDict objectForKey: person.firstName]){ NSMutableArray *array = [myDict objectForKey: person.firstName]; [array addObject:person]; [myDict setObject: array forKey:person.firstName]; }else{ NSMutableArray *array = [NSMutableArray arrayWithObject:person]; [myDict setObject: array forKey:person.firstName]; } } NSLog(@"myDict %@", myDict); //Result myDict will give the desired output. 

But is there a better way to do this?

If I use @distinctUnionOfObjects , I can only group string objects (Not such user objects. Right?).

Thanks for the reply in advance.

+8
objective-c iphone cocoa
source share
6 answers

Checkout, it is very similar to what you want

stack overflow

The code in your case will be as follows:

 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); 
+11
source share

You can try this normal sorting of objects for an array.

 NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"Firstname" ascending:NO selector:@selector(compare:)]; [Array sortUsingDescriptors:[NSArray arrayWithObjects:sortDescriptor, nil]]; 
+3
source share

I created a small library called Linq-to-ObjectiveC that provides a number of methods to simplify querying arrays. To perform the required group operation, you can simply do the following:

 NSDictionary* groupedByName = [personsArray groupBy:^id(id person) { return [person firstName]; }]; 

This will return a dictionary in which the keys are separate first names, and each value is an array of "person" objects that have a given name.

+3
source share
 - (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; } 
+1
source share

A Remove the code to help you do this,

  -(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 is the key key or keypath .

0
source share

NSArray no built-in group by method. Your example implementation can be added as a category.

Unfortunately, the @distinctUnionOfObjects operation will return the rows of the firstName property: John, David. It will not perform a group by operation and there will be no such operation.

Collection Operations

0
source share

All Articles