【问题标题】:Remove duplicate values from NSArray while appending追加时从 NSArray 中删除重复值
【发布时间】:2014-01-29 03:51:44
【问题描述】:

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

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

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

执行此操作时,由于 setArray,我的 mutArrayA 被 arrayB 中的对象替换。有没有更快的方法可以在不重复的情况下追加数组。

【问题讨论】:

    标签: ios objective-c nsmutablearray nsarray duplicates


    【解决方案1】:
    [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 不会删除重复项,因为它认为它们不是重复项,因此通过覆盖此方法,您可以为其提供如何比较对象是否相等的线索

    【讨论】:

    • 这对我不起作用。运行代码后,它在 mutArrayA 中给了我重复项。
    • 那么知道 NSSet 如何检查重复项吗?它是否检查对象的内容或其指针值?
    • 我想它会检查它们的哈希值
    • 嗯,那可能是它不适合我的原因。
    • 这里有一个关键的区别。当您说重复时,您是指 isEqual 意义上的,还是具有相等的值?您可能需要覆盖您的 isEqual 方法来获得您所追求的行为。看看这段代码。
    【解决方案2】:

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

    - (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;
    }
    

    【讨论】:

      【解决方案3】:

      试试这个,

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

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

        • 按顺序是指排序顺序吗?我在追加后对 mutArrayA 进行排序,所以我猜这应该不是问题
        • 不过,我会尝试一下您的解决方案以了解它是如何工作的。
        • 一个 NSSet/NSMutableSet 将持有不同对象的无序集合。因此对象不会位于不同的索引处,也不会每次都以相同的顺序从集合中出来。从集合中检索后对数组进行排序将正常工作。
        • 不,这个解决方案也没有帮助我。我想知道它是否是创建问题的数据格式,或者 [set allObjects] 可能正在检查对象的指针值。我在两个数组中的数据都是这种格式: { key = Testing 123; value = 测试应用 },
        【解决方案5】:

        您应该在这里做出一个关键的区分。当您说重复时,您是指 isEqual 意义上的,还是具有相等的值?您可能需要覆盖您的 isEqual 方法来获得您所追求的行为。如果您使用自定义对象,默认情况下,您的自定义对象只有在它们具有相同的指针引用时才相等。 IE。

        [[[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];
        

        【讨论】:

          【解决方案6】:

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

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

          这是一个NSArray category,用于获取不同的数组。

          【讨论】:

            【解决方案7】:

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

            我想合并两个 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
            )
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-04-20
              • 1970-01-01
              • 2016-10-26
              • 2016-01-06
              相关资源
              最近更新 更多