I have an NSMutableArray that contains a few custom objects. Two of the objects have the same properties such as title and author. I want to remove the duplicate object and leave the other.
Asset *asset;
NSMutableArray *items = [[[NSMutableArray alloc] init] autorelease];
// First
asset = [[Asset alloc] init];
asset.title = @"Developer";
asset.author = @"John Smith";
[items addObject:asset];
[asset release];
// Second
asset = [[Asset alloc] init];
asset.title = @"Writer";
asset.author = @"Steve Johnson";
[items addObject:asset];
[asset release];
// Third
asset = [[Asset alloc] init];
asset.title = @"Developer";
asset.author = @"John Smith";
[items addObject:asset];
[asset release];
Since they are NOT the same object, but only having duplicate properties, how can I remove the duplicate?
First, I'd override the isEqual: method for Asset like this:
Then, if you want to avoid placing duplicates in the array in the first place:
If the array already contains duplicates, then any algorithm that finds them has a run time already worse than linear, but I think creating a new array and only adding unique elements like above is the best algorithm. Something like this:
In the worst case scenario (all elements are already unique) the number of iterations is:
Which is still O(n^2) but is slightly better than @Justin Meiners' algorithm. No offense! :)
If you'd like your custom NSObject subclasses to be considered equal when their names are equal you may implement
isEqual:
andhash
. This will allow you to add of the objects to anNSSet
/NSMutableSet
(a set of distinct objects).You may then easily create a sorted
NSArray
by usingNSSet
'ssortedArrayUsingDescriptors:
method.MikeAsh wrote a pretty solid piece about implementing custom equality: Friday Q&A 2010-06-18: Implementing Equality and Hashing
You could create a HashSet and as you loop, you could add "title+author" concatenated set to the HashSet (NSMutableSet). As you arrive at each item, if the HashSet contains your key, either remove it or don't copy (either deleting or creating a copy without duplicates).
That makes it order n (1 loop)
Here's the NSMutableSet class:
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSMutableSet_Class/Reference/NSMutableSet.html#//apple_ref/occ/cl/NSMutableSet
EDIT with code:
The meat of the code is the one loop.
Here's the output:
You can use the uniqueness of an
NSSet
to get distinct items from your original array. If you have the source code forAssest
you will need to override thehash
andisEqual:
method on theAsset
class.Then to implement:
And if you need an array at the end you can just call
[distinctItems allObjects]
This is one way you could do it :