I have a problem creating an NSMutableArray from an array of custom objects to an array of arrays of dictionaries and lone dictionaries (not in an array).
I currently have an NSMutableArray of Person objects. I iterate through these Person objects to create NSDictionaries of each. These dictionaries have three keys:
NSString *firstName;
NSString *lastName;
Person *id;
Some of these dictionaries will have the exact same first and last name, but the Person id will always be different. I'd like to convert this NSMutableArray of Person objects to an NSMutableArray of NSMutableArrays and NSDictionaries - the NSMutableArrays would be NSDictionaries that have the same firstName and lastName, and the lone NSDictionaries would be objects that do not have a firstName and lastName in common with any other Person in the original NSMutableArray.
A visual of the end result I desire is below:
| |-- NSDictionary (john, smith, id)
| |-- NSDictionary (john, smith, id)
|-- NSMutableArray |-- NSDictionary (john, smith, id)
| |-- NSDictionary (john, smith, id)
| |-- NSDictionary (john, smith, id)
|
| |-- NSDictionary (bill, jones, id)
people |-- NSMutableArray |-- NSDictionary (bill, jones, id)
(NSMutableArray) | |-- NSDictionary (bill, jones, id)
|
|-- NSDictionary (mike, smith, id)
|
|-- NSDictionary (mike, jones, id)
|
|-- NSDictionary (john, jones, id)
My current implementation is below:
- (NSMutableArray*)organizeForSearchResults:(NSMutableArray*)c {
NSMutableArray *returnArray = [NSMutableArray alloc] init];
// iterate through every person in the incoming crate
@autoreleasepool {
for (Person *person in c) {
// create a new person dictionary
NSDictionary *personDictionary = [[NSDictionary alloc] initWithObjectsAndKeys:
person, @"person",
person.firstName, @"firstName",
record.lastName, @"lastName",
nil];
// if there are already objects in the top level c array
if (returnArray.count > 0) {
for (id object in returnArray) {
// the object in returnArray is an array of record dictionaries
if ([object isKindOfClass:[NSMutableArray class]]) {
// if the first dictionary object in the array has the same firstName
// and lastName, add the new person dict to the existing array of dicts
NSString *firstName = [(NSDictionary*)object[0] objectForKey:@"firstName"];
NSString *lastName = [(NSDictionary*)object[0] objectForKey:@"lastName"];
if ([firstName isEqualToString:person.firstName] && [lastName isEqualToString:person.lastName]) {
[object addObject:personDictionary];
}
}
// if the object is a person dictionary, see if it matches the current dictionary
else if ([object isKindOfClass:[NSDictionary class]]) {
NSString *firstName = [(NSDictionary*)object objectForKey:@"firstName"];
NSString *lastName = [(NSDictionary*)object objectForKey:@"lastName"];
// if the current object matches the new person dict, we need to
// create a new array with both the existing person dict and the
// new person dict, add that array to returnArray, and remove the
// old person dict
if ([firstName isEqualToString:record.firstName] && [lastName isEqualToString:record.lastName]) {
NSMutableArray *newArray = [[NSMutableArray alloc] initWithCapacity:2];
[newArray addObject:object];
[newArray addObject:personDictionary];
[returnArray addObject:newArray];
[returnArray removeObject:object];
}
// the new person dict does not match an existing array, so add it as
// a single item in personArray
else {
[personArray addObject:personDictionary];
}
}
}
}
// there are no objects in personArray, so just add this person dict
else {
[personArray addObject:personDictionary];
}
}
}
return personArray;
}
The implementation that I have so far is functionally correct, I believe, but I am obviously getting *** Collection <__NSArrayM:> was mutated while being enumerated. errors, as I am modifying the NSMutableArray while it is being enumerated. I feel that I am completely lost on how to implement this correctly - does anyone have another strategy on how to accomplish this?