2

Hi in one of my application,I have an array which contains a group of NSMutableDictionary objects. The dictionary object have three key-value pairs as like below

  1. company
  2. product
  3. quantity

And array having many number of objects. Here now by using different add buttons I am adding these dictionary objects to the array. Even while adding objects to array i am checking whether any duplicate objects are available or not using NSNotFound method. As such below

if([Array indexOfObject:dicObject] == NSNotFound)
{  
        [Array addObject:dicObject];
}

Here it is working fine in few cases, But it's not working in other cases.I will explain with one example :

  1. For example i have one dicobject in array with following key value pairs

    company:XYZ Product:ABC Quantity:2

Now for example I want to add one more dic object with the same above key value pairs. That time obviously it won't add because already same product is available in array.

This is valid condition.

Exceptional Case: For example I want to add one more product with following values

Company:XYZ    Product:ABC   Quantity:6

At this case this product is adding into the array without any error. But my concern is i don't want to add this into the array again only the quantity have to update, because company and product name both are same so. So can you please show me the way to handle this scenario.

2
  • Hi Rushabh thanks for your reply. Actually i need to avoid duplicates in array not in dictionary.My array have dictionary objects . Commented Jul 1, 2013 at 9:22
  • Hey dude have you tried NSSet or NSOrderedSet, both which don't allow duplicates and can easily be converted from an array and to an array. NSSet Doc Commented Jul 1, 2013 at 9:48

2 Answers 2

5

You could use indexOfObjectPassingTest: to know if a similar dictionary is already present in the array.

This may look something like this:

NSMutableArray *arr = // your array
NSDictionary *dicObject = // your object

NSUInteger indexOfDicObject = [arr indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop)
{
    return ([obj[@"company"] isEqualToString:dicObject[@"company"]] &&
            [obj[@"product"] isEqualToString:dicObject[@"product"]]);
}];

if (indexOfDicObject == NSNotFound)
{
    [arr addObject:dicObject];
}
else
{
    NSNumber *quantity = arr[indexOfDicObject][@"quantity"];
    arr[indexOfDicObject][@"quantity"] = @([quantity intValue] + [dicObject[@"quantity"] intValue]);
}

I made the following assumptions:

  • the company value is a NSString;
  • the product value is a NSString;
  • the quantity value is an integer, stored in a NSNumber.

See also trojanfoe's answer, which is better if you can replace your dictionaries by classes.

Sign up to request clarification or add additional context in comments.

2 Comments

Very nice and clean solution! I didn't know that method! +1
Hi Guillaume Algis thanks for your reply your answer is some what helped me.
3

I think you need to change tack; first create a custom object to hold your company, product and quantity and ensure you implement the isEqual: and hash methods.

Then simply store your custom objects within an NSMutableSet object, which will ensure that duplicates cannot exist.

Your custom object will now become your principle Model object for the app (i.e. provide the 'M' in MVC, the design pattern upon which Cocoa and Cocoa Touch apps are based) and you will find that it will be reused over and over as the app grows.

4 Comments

I like this approach, because once the custom object is written the code should look simple. However, he also needs to include a way of "automatically" adding the quantity properties together when the object has the same company and product.
@boyfarrell Isn't that a case of ignoring quantity in the isEqual: comparison, and checking if the object exists before adding it (in which case he will update quantity if it does)? I don't think this can be done "automatically" however.
I like this, this seems quite elegant. However it will probably require to change more code for gadamsetty.
Agreed; however you end up with a model object which will be useful throughout the app. It provides the M in MVC.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.