Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm trying to loop through my array and find duplicate objects based on the name properties of the objects in the array. Once a duplicate is found I need to combine these objects, the name and unit values stay the same, I just want to add the quantity values together. At this point I want to remove the two duplicates and add the new object to the array instead.

If its two difficult to remove two objects and add another (might mess with the index?) then the new objects could be added to a filtered array, as long as when a duplicate isnt found that is also added to this array. So the new array will contain all of my previous values, with duplicate values combine on quantity.

I have this so far:

NSMutableSet* existingNames = [NSMutableSet set];
NSMutableArray* filteredArray = [NSMutableArray array];

for (id object in ingredientsArray)
{
    if (![existingNames containsObject:[object name]])
    {
        [existingNames addObject:[object name]];
        NSLog(@"%@", @"DUPLICATE FOUND");

        //create new object to store the new info in.
        ingredient *info = [[ingredient alloc] initWithname:[object name] quantity:[/* How do I add the quanitity values of the two objects that are duplicates here? */] unit:[object unit]];

        //add this to filtered array.
        [filteredArray addObject:object];

        //remove object from array.
        [ingredientsArray removeObject:object];
    }
}

thanks

share|improve this question
You could just create a new array that holds the previous values, and combines the duplicate values. – msgambel Sep 8 at 18:13

1 Answer

up vote 1 down vote accepted

You cannot modify an array that you are enumerating. The compiler should complain about this, if not, it should crash at runtime.

I think the logic in your code is bit messed up. The if clause checks if the string is not contained in your duplicates array - so "DUPLICATE FOUND" is certainly not true.

It is bad practice to just iterate through id in this case. It would be better if you could type your objects more strongly. It is also advised to adhere to the conventions such as Capitalized class names.

One trick to reduce the iterations is to just iterate through the unique names. There is a trick with NSSet to accomplish this:

NSArray *names = [ingredientsList valueForKeyPath:@"name"];
NSSet *uniqueNames = [NSSet setWithArray:names];
NSArray *resultArray = [NSMutableArray array];
NSPredicate *nameFilter;

for (NSString *ingredientName in uniqueNames) {
   predicate = [NSPredicate predicateWithFormat:@"name = %@", ingredientName];
   NSArray *entries = [ingredientsList filteredArrayUsingPredicate:predicate];
   Ingredient *ingredient = entries[0];
   if (entries.count > 1) {
      NSLog(@"Found %d instances of %@.", entries.count, ingredientName);
      NSNumber *sum = [entries valueForKeyPath:@"@sum.quantity"];
      ingredient.quantity = sum;
   }
   [resultsArray addObject:ingredient];
}

This assumes that the class Ingredient has at least two properties, name (NSString) and quantity (NSNumber). This also works with plain NSDictionaries.

share|improve this answer
Prefect, thank you! – Lewis Sep 8 at 18:38

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.