【问题标题】:How to extract unique objects from multiple arrays如何从多个数组中提取唯一对象
【发布时间】:2016-03-17 12:01:01
【问题描述】:

编辑:
我有两个不同的数组,其中包含一些重复的字符串,我想用唯一的字符串创建一个新数组。

例如,取这两个数组:

NSArray *array1 = [[NSArray alloc] initWithObjects:@"a",@"b",@"c",nil]; 
NSArray *array2 = [[NSArray alloc] initWithObjects:@"a",@"d",@"c",nil];

// Result should be an array with objects "b", and "d" 
// since they are the only two that are not repeated in the other array.

【问题讨论】:

标签: objective-c ios5 nsarray


【解决方案1】:

编辑:

// Your starting arrays
NSArray *array1 = [[NSArray alloc] initWithObjects:@"a",@"b",@"c",nil]; 
NSArray *array2 = [[NSArray alloc] initWithObjects:@"a",@"d",@"c",nil];

// Create two new arrays that only contain the objects 
// which are not in the other array:
NSMutableArray *uniqueElementsInArray1 = [array1 mutableCopy];
[uniqueElementsInArray1 removeObjectsInArray:array2];

NSMutableArray *uniqueElementsInArray2 = [array2 mutableCopy];
[uniqueElementsInArray2 removeObjectsInArray:array1];

// Combine the two arrays.
// Result contains objects @"b" and @"d":
NSArray *result = [uniqueElementsInArray1 arrayByAddingObjectsFromArray:uniqueElementsInArray2];

【讨论】:

  • NSArray *array1 = [[NSArray alloc] initWithObjects:@"a",@"b",@"c",nil]; NSArray *array2 = [[NSArray alloc] initWithObjects:@"a",@"d",@"c",nil];
  • 所以你有两个数组,想要找到只出现在其中一个数组中的字符串?这似乎与您在问题中提出的有点不同。
  • 这回答了你的问题吗?
  • 太棒了!欢迎来到 SO(堆栈溢出)!当人们回答您的问题时,请务必单击答案左上角的复选标记,以便我们为您提供帮助而获得荣誉。最好单击所有有帮助的答案以及您接受的答案上的向上箭头。
【解决方案2】:

为此,您只需声明另一个临时 NSMutableArray 。从原始数组中检索您拥有的任何数据,例如 objectArray。检查临时数组是否有,并将其放入临时数组。只需参考以下代码:

    for(NSString *str in objectArray)
    {

        if(![tempArray containsObject:str])
        {

            [tempArray addObject:str];

        }
    }

在此之后你可以继续使用 tempArray 或将 tempArray 放入 objectArray 如果你想进一步使用 objectArray。我认为这对你有用。

【讨论】:

    【解决方案3】:

    你可以使用 NSSet 作为过滤器(想想你脑海中的维恩图):

    NSArray *array1 = @[@1,@2,@3,@4,@2,@3];
    NSArray *array2 = @[@3,@4,@5,@6,@4,@6];
    
    NSSet *set1 = [NSSet setWithArray:array1]; // [1,2,3,4]
    NSSet *set2 = [NSSet setWithArray:array2]; // [3,4,5,6]
    
    方法1(我最喜欢的):
    NSMutableSet *mSet1 = [set1 mutableCopy];
    NSMutableSet *mSet2 = [set2 mutableCopy];
    
    [mSet1 minusSet:set2]; // mSet1 = [1,2]
    [mSet2 minusSet:set1]; // mSet2 =  [5,6]
    
    [mSet1 unionSet:mSet2]; // mSet1 = [1,2,5,6], only the unique elements.
    
    // Now just put it in an immutable collections with a self-docu name...
    NSArray *arrayOfUniqueness = [setOfUniqueElementsOnly allObjects];
    
    方法2(更明确的测试,不需要维恩图):
    NSSet *setOfObjsUniqueTo1 = [set1 objectsPassingTest:^BOOL(id  _Nonnull obj, BOOL * _Nonnull stop) {
        return ![set2 containsObject:obj];
    }]; // [1,2]
    
    NSSet *setOfObjsUniqueTo2 = [set2 objectsPassingTest:^BOOL(id  _Nonnull obj, BOOL * _Nonnull stop) {
        return ![set1 containsObject:obj];
    }]; // [5,6]
    
    NSMutableSet *oneSetToRuleThemAll = [NSMutableSet setWithSet:setOfObjsUniqueTo1];
    // [1,2]
    [oneSetToRuleThemAll unionSet:setOfObjsUniqueTo2]; // [1,2,5,6]
    
    // Or as an array:
    NSArray *anotherArrayOfUniqueness = [oneSetToRuleThemAll allObjects];
    
    方法 3(避开NSSet,但我不会在正式晚宴上将此代码放在英国女王对面——这很不雅):
    NSMutableArray *mArray1 = [NSMutableArray new];
    NSMutableArray *mArray2 = [NSMutableArray new];
    
    NSIndexSet *uniqueIndexes1 = [array1 indexesOfObjectsPassingTest:^BOOL(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        return ![array2 containsObject:obj];
    }]; // [0,1,4] (b/c @1 and @2 are unique to array1)
    
    [uniqueIndexes1 enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) {
        [mArray1 addObject:array1[idx]];
    }]; // @[@1,@2,@2]
    
    NSIndexSet *uniqueIndexes2 = [array2 indexesOfObjectsPassingTest:^BOOL(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        return ![array1 containsObject:obj];
    }]; // [2,3,5] (b/c @5 and @6 are unique to array2)
    
    [uniqueIndexes2 enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) {
        [mArray2 addObject:array2[idx]];
    }]; // @[@5,@6,@6]
    
    NSArray *unionArray = [array1 arrayByAddingObjectsFromArray:array2];
        // @[@1,@2,@2,@5,@6,@6]
    
    NSArray *yetAnotherArrayOfUniqueness = [[NSSet setWithArray:unionArray] allObjects];
        // @[@1,@2,@5,@6]
    

    不是提问者的问题,而是要获得一个删除重复项的数组(即,每个元素都是唯一的),可以做类似的魔法:

    //given...
    NSArray *arr1 = @[@"a", @"b", @"c"];
    NSArray *arr2 = @[@"b", @"c", @"d"];
    
    //...make a single array to rule them all:
    NSArray *temp = [arr1 arrayByAddingObjectsFromArray:arr2];
    //[a,b,c,b,c,d]
    
    //Make an NSSet from the two:
    NSSet *filterSet = [NSSet setWithArray:temp]; // Set has: a,b,c,d
    
    //Finally, transmogrify that NSSet into an NSArray:
    NSArray *arrayOfUniqueness = [filterSet allObjects]; // [a,b,c,d]
    

    根据Apple Docs(已添加重点):

    +setWithArray: 创建并返回一个集合,其中包含给定数组中包含的对象的唯一集合。

    更新:类似问题请参见此处:Remove all strings with duplicates in an NSArray

    【讨论】:

    • 这没有回答最初的问题,但正是我想要的。 A+++
    • 感谢您的收看!固定的;我很高兴它有所帮助。
    【解决方案4】:

    使用Set作为过滤器,例如:

    String[] arr = {"a","a","b"};
    Object[] uniqueArr = (Object[])new HashSet<String>(Arrays.asList(arr)).toArray();
    

    【讨论】:

    • 这个问题是关于Objective-C的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    • 2019-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-03
    • 2016-07-18
    相关资源
    最近更新 更多