NSArray: Remove objects with duplicate properties

前端 未结 5 1814
迷失自我
迷失自我 2020-12-15 10:12

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 an

5条回答
  •  伪装坚强ぢ
    2020-12-15 10:32

    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.

    void print(NSMutableArray *assets)
    {
        for (Asset *asset in assets)
        {
            NSLog(@"%@/%@", [asset title], [asset author]);
        }
    }
    
    int main (int argc, const char * argv[])
    {
    
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    
        //
        // Create the initial data set
        //
        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];
    
        NSLog(@"****Original****");
        print(items);
    
        //
        // filter the data set in one pass
        //
        NSMutableSet *lookup = [[NSMutableSet alloc] init];
        for (int index = 0; index < [items count]; index++)
        {
            Asset *curr = [items objectAtIndex:index];
            NSString *identifier = [NSString stringWithFormat:@"%@/%@", [curr title], [curr author]];
    
            // this is very fast constant time lookup in a hash table
            if ([lookup containsObject:identifier])
            {
                NSLog(@"item already exists.  removing: %@ at index %d", identifier, index);
                [items removeObjectAtIndex:index];
            }
            else
            {
                NSLog(@"distinct item.  keeping %@ at index %d", identifier, index);
                [lookup addObject:identifier];
            }
        }
    
        NSLog(@"****Filtered****");
        print(items);
    
        [pool drain];
        return 0;
    }
    

    Here's the output:

    Craplet[11991:707] ****Original****
    Craplet[11991:707] Developer/John Smith
    Craplet[11991:707] Writer/Steve Johnson
    Craplet[11991:707] Developer/John Smith
    Craplet[11991:707] distinct item.  keeping Developer/John Smith at index 0
    Craplet[11991:707] distinct item.  keeping Writer/Steve Johnson at index 1
    Craplet[11991:707] item already exists.  removing: Developer/John Smith at index 2
    Craplet[11991:707] ****Filtered****
    Craplet[11991:707] Developer/John Smith
    Craplet[11991:707] Writer/Steve Johnson
    

提交回复
热议问题