views:

31

answers:

1

Hi, I have the following problem and I cannot figure out how to solve it. I have an NSSet which contains Person objects (NSDictionary with 2 keys: name, age). From time to time I get an NSArray of Person objects and I want to add them to my NSSet but I want to filter out the duplicates. I'm thinking I could use NSPredicates but I am reading the documentation and I can't understand how should I format my NSPredicate to filter out my array content based on what I already have in NSSet.

So I have an NSSet with 5 custom objects and I get an NSArray with 6 objects but 3 of them already exist in NSSet and I want to filter them out. I understand what I should do with basic objects like Strings, integers, etc but I don't know how to extend this to work with custom more complex objects.

I hope I was clear enough with my problem. Any starting point, example or advice is much appreciated.

Thank you!

A: 

If you already have a mutable set, you don't really have to do anything special. If you get the same Person instance back at some point in the future, addObject: will simply ignore it. If you have a different meaning of "equality" than just whether two objects are the same instance, then you have to deal with that yourself, but if your new object returns YES for isEqual: then addObject: will already ignore it as well when you place it in the set.

Jason Coco
Yes, you are right, this should happen but it doesn't. I have investigated the problem a little more. I have my NSSet with lets say 5 integers {0, 1, 2, 3, 4, 5} if I try to append an NSArray of size 5 {1, 0, 3, 2, 5, 4} it will append it to the NSSet even though it is the same thing but in different order. I've tested my isEqual call and it works right. Do you have any ideas why do I get this behaviour?
Horatiu Paraschiv
Add each item in the array. Since NSSet works on objects, it is simply adding a reference to your array to the set.
Jason Coco
I've found the real problem. I didn't override the hash method and NSSets methods use the object's hash code too to evaluate objects. So now I have to figure out a way of creating equal hash codes for equal objects. I'll post later the solution.
Horatiu Paraschiv
Ok so the conclusion is: NSSet uses hash codes to determine if 2 objects are equal so always override hash method when you override isEqual. Two distinct instances may be logically equal according to the class’s equals method, but to the Object class’s hash method, they’re just two objects with nothing much in common. More details about this here:http://java.sun.com/developer/Books/effectivejava/Chapter3.pdf
Horatiu Paraschiv
That link is specific to Java. Equality of objects is discussed in Collections Programming Guide for Cocoa as well as the documentation for NSObject.
Jason Coco
Yes you are right but the theory fits well here too. Thank you for your assistance!
Horatiu Paraschiv