在追加时从NSArray中删除重复值

时间:2014-01-29 03:51:44

标签: ios objective-c nsmutablearray nsarray duplicates

我有2个数组,其中一个是NSMutableArray(比如mutArrayA),另一个是NSArray(arrayB)。 我将arrayB附加到mutArrayA,同时我想删除重复项,如果有的话,我不想在mutArrayA中复制任何内容。

我知道这样做的一种方法是迭代arrayB中的每个对象并使用indexOfObject检查其索引(如果在mutArrayA中找到),则不要将该对象追加到mutArrayA,否则追加它。但是我试图寻找一些更快的方法来实现这一点,我在这个网站上遇到了以下解决方案,如下所示:

[mutArrayA setArray:[[NSSet setWithArray:arrayB] allObjects]];

当我执行此操作时,由于setArray,我的mutArrayA被arrayB中的对象替换。有没有更快的方法使用它可以附加数组而不会获得重复项。

7 个答案:

答案 0 :(得分:2)

[mutArrayA addObjectsFromArray:[[NSSet setWithArray:arrayB] allObjects]];
[mutArrayA setArray:[[NSSet setWithArray:mutArrayA] allObjects]];

所以最初你从arrayB中删除重复项,附加它,然后应用相同的原则来删除mutArrayA中的重复项,如果有任何后续附加

更新

您需要为您的班级覆盖isEqual:方法。我假设你的对象包含NSString个对象,给你一个例子。

- (BOOL)isEqual:(MyClass *)object
{
  return [self.key isEqualToString:object.key] && [self.value isEqualToString:object.value];
}

您还需要覆盖hash这样的方法:

- (NSUInteger)hash {
return [self.key hash] ^ [self.value hash];
}

问题是NSSet没有删除重复项,因为它认为它们不是重复的,所以通过重写这个方法,你可以给它一个如何比较你的对象是否相等的线索

答案 1 :(得分:1)

实现以下方法并使用要遍历的数组调用它。

- (NSMutableArray *)removeDuplicates:(NSMutableArray *)array{
    NSArray *copy = [array copy];
    NSInteger index = [copy count] - 1;
    for (id object in [copy reverseObjectEnumerator]) {
        if ([array indexOfObject:object inRange:NSMakeRange(0, index)] != NSNotFound) {
            [array removeObjectAtIndex:index];
        }
        index--;
    }
    [copy release];
    copy = nil;
    return array;
}

答案 2 :(得分:0)

试试这个,

[mutArrayA addObjectsFromArray: arrayB];
[mutArrayA setArray:[[NSSet setWithArray:mutArrayA] allObjects]];

答案 3 :(得分:0)

将两个数组放入一个将删除重复项的集合中,但不保证顺序。如果订单很重要,则需要使用另一种解决方案。

NSMutableSet *set = [[NSMutableSet alloc] init];
[set addObjectsFromArray:mutArrayA];
[set addObjectsFromArray:arrayB];

mutArrayA = [[set allObjects] mutableCopy];

答案 4 :(得分:0)

你应该在这里做一个关键的区别。当你说复制品的意思是在等等意义上,还是具有相同的价值?您可能需要覆盖isEqual方法以获取您正在进行的行为。如果使用自定义对象,则默认情况下,如果自定义对象具有相同的指针引用,则它们仅相等。即。

[[[MyCustomObject alloc]init]isEqual:[[MyCustomObject alloc]init]] == No;

Whereas 

[[[NSString alloc] init] isEqual:[[NSString alloc] init]] == YES;

假设您正确处理isEqual(或实现自己的方法来确定相等性),您可以将数组转换为NSSet,然后按照之前的建议返回。

NSSet *compositeSet = [NSSet setWithArray:[mutArrayA addObjectsFromArray:mutArrayB]];
NSArray *deduplicatedArray = [compositeSet allObjects];

答案 5 :(得分:0)

KVC对象运算符@distinctUnionOfObjects在这里可能会有所帮助。

[mutArrayA addObjectsFromArray:arrayB];
uniquearray = [mutArrayA valueForKeyPath:@"@distinctUnionOfObjects.self"];

这是获取不同数组的NSArray category

答案 6 :(得分:0)

这可能不适用于原始海报的问题,但此页面是我使用的条款的第一个搜索结果,所以我在此处发布我的解决方案以防其他人帮助。

我想合并两个NSStrings数组(它们都被用作NSDictionaries中的键),但我需要保持第一个数组的排序顺序。所以我想要一个由排序数组组成的数组,以及第二个数组中的任何唯一值。我使用了以下代码:

NSArray *sortedArray = @[@"Aardvark", @"Bandicoot", @"Catbird", @"Dingo", @"Elephant shrew", @"Flagellate"];
NSArray *array2 = @[@"Zebra", @"Aardvark", @"Yak", @"Dingo", @"Xeromys"];

NSMutableArray *nonDupes = [NSMutableArray arrayWithArray:array2];
[nonDupes removeObjectsInArray:sortedArray];
NSArray *combinedArray = [sortedArray arrayByAddingObjectsFromArray:nonDupes];

NSLog(@"combinedArray: %@", combinedArray);

输出:

2017-05-01 14:46:39.860 App [23038:6945531] combinedArray: (
    Aardvark,
    Bandicoot,
    Catbird,
    Dingo,
    "Elephant shrew",
    Flagellate,
    Zebra,
    Yak,
    Xeromys
)