Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove duplicates from array comparing the properties of its objects

Suppose I have a class Event, and it has 2 properties: action (NSString) and date (NSDate).

And suppose I have an array of Event objects. The problem is that "date" properties can match.

I need to remove the duplicates, meaning that 2 different objects with the same date IS a duplicate.

I can remove duplicates in any array of strings or nsdates, they are easy to compare. But how to do it with complex objects, where their properties are to be compared?

Don't ask me what I did so far, cos' the only thing coming in my mind is a bubble sort, but it's a newbie solution, and slow.

Quite any help is highly appreciated (links, tuts, code).

Thanks in advance.

EDIT

Thanks to dasblinkenlight, I have made a custom method:

- (NSArray *)removeDuplicatesInArray:(NSArray*)arrayToFilter{

    NSMutableSet *seenDates = [NSMutableSet set];
    NSPredicate *dupDatesPred = [NSPredicate predicateWithBlock: ^BOOL(id obj, NSDictionary *bind) {
        YourClass *e = (YourClass*)obj;
        BOOL seen = [seenDates containsObject:e.propertyName];
        if (!seen) {
            [seenDates addObject:e.when];
        }
        return !seen;
    }];
    return [arrayToFilter filteredArrayUsingPredicate:dupDatesPred];
} 

Here YourClass is the name of your class the object belongs to, and propertyName is the property of that object you are going to compare.

Suppose self.arrayWithObjects contains the objects of YourClass.

After populating it, use

self.arrayWithObjects = [self removeDuplicatesInArray:self.arrayWithObjects];

and you are done.

All credits to dasblinkenlight. Cheers!

like image 296
John Smith Avatar asked Nov 21 '12 17:11

John Smith


1 Answers

You can create an NSMutableSet of dates, iterate your event list, and add only events the date for which you have not encountered before.

NSMutableSet *seenDates = [NSMutableSet set];
NSPredicate *dupDatesPred = [NSPredicate predicateWithBlock: ^BOOL(id obj, NSDictionary *bind) {
    Event *e = (Event*)obj;
    BOOL seen = [seenDates containsObject:e.date];
    if (!seen) {
        [seenDates addObject:e.date];
    }
    return !seen;
}];
NSArray *events = ... // This is your array which needs to be filtered
NSArray *filtered = [events filteredArrayUsingPredicate:dupDatesPred];
like image 186
Sergey Kalinichenko Avatar answered Oct 13 '22 01:10

Sergey Kalinichenko