简体   繁体   English

比较两个数组并获得常用项

[英]compare two arrays and get the common items

I have two arrays, but they have different lengths . 我有两个数组,但它们有不同的长度 I want to compare these two arrays and put common items to a new array . 我想比较这两个数组并将常用项放入一个新数组 meanwhile there should not be have duplicate items is the third array. 同时不应该有重复的项目是第三个数组。 I really mess up with this, please give me a help. 我真的搞砸了,请给我一个帮助。 highly thankful . 非常感谢。 . .

Something like this? 像这样的东西?

NSMutableSet* set1 = [NSMutableSet setWithArray:array1];
NSMutableSet* set2 = [NSMutableSet setWithArray:array2];
[set1 intersectSet:set2]; //this will give you only the obejcts that are in both sets

NSArray* result = [set1 allObjects];

This has the benefit of not looking up the objects in the array, while looping through another array, which has N^2 complexity and may take a while if the arrays are large. 这样做的好处是不会查找数组中的对象,同时循环遍历另一个阵列,该阵列具有N ^ 2的复杂性,如果阵列很大,可能需要一段时间。

Edit: set2 doesn't have to be mutable, might as well use just 编辑:set2不必是可变的,也可以使用

NSSet* set2 = [NSSet setWithArray:array2];

A third approach (besides using sets or the simple loop checking each item with contains) would be to sort both arrays, and then use two indices: 第三种方法(除了使用集合或简单循环检查包含contains的每个项目)将对两个数组进行排序 ,然后使用两个索引:

// approach using sets:

NSArray *arrayUsingSets(NSMutableArray *arr1, NSMutableArray *arr2)
{
    NSMutableSet *set1 = [NSMutableSet setWithArray: arr1];
    NSSet *set2 = [NSSet setWithArray: arr2];
    [set1 intersectSet: set2];
    return [set1 allObjects];
}

// my approach:

NSArray *arrayUsingComp(NSMutableArray *arr1, NSMutableArray *arr2)
{
    NSMutableArray *results = [NSMutableArray arrayWithCapacity: arr1.count + arr2.count];

    // Assumes input arrays are sorted. If not, uncomment following two lines.
//    [arr1 sortUsingSelector: @selector(compare:)];
//    [arr2 sortUsingSelector: @selector(compare:)];

    int i = 0;
    int j = 0;
    while ((i < arr1.count) && (j < arr2.count))
    {
        switch ([[arr1 objectAtIndex: i] compare: [arr2 objectAtIndex: j]])
        {
            case NSOrderedSame:
                [results addObject: [arr1 objectAtIndex: i]];
                i++, j++;
                break;
            case NSOrderedAscending:
                i++;
                break;
            case NSOrderedDescending:
                j++;
                break;
         }
    }

    // NOTE: results are sorted too.
    // NOTE 2: loop must go "backward".
    for (NSInteger k = results.count - 1; k > 0; k--) 
        if ([[results objectAtIndex: k] isEqual: [results objectAtIndex: k-1]])
            [results removeObjectAtIndex: k];

    return results;    
}

I did some simple profiling, and if I make mutable copies of the arrays passed in, and sort those, it performs 1.5 times slower than the approach using sets. 我做了一些简单的分析,如果我制作传入的数组的可变副本,并对它们进行排序,它的执行速度比使用集合的方法慢1.5倍 My approach above seems to perform 1.5 times faster than the approach using sets. 我上面的方法似乎比使用集合的方法快1.5倍 If the arrays are guaranteed to be sorted already, my approach will perform even better yet ( almost 4 times as fast as the version using sets), since no sorting is required. 如果保证阵列已经被排序,我的方法将表现得更好( 几乎是使用集合的版本的4倍 ),因为不需要排序。

Update: 更新:

This did not eliminate duplicates, so I added the loop at the end of the routine. 这并没有消除重复,所以我在例程结束时添加了循环。 Now it is only 3 times as fast as the approach using sets, but still... 现在它只是使用套装的方法的3倍 ,但仍然......

Iterate over array1 & search for it in array2. 迭代array1并在array2中搜索它。 If it is found, add it to array3 if it does not have it already. 如果找到,请将其添加到array3(如果尚未添加)。

for (MyObject* obj in array1)
{ 
     if([array2 containsObject:obj] && ![array3 containsObject:obj])
        [array3 addObject:obj];
}

If your array1 does not have duplicate items, you don't need the 2nd check. 如果您的array1没有重复项,则不需要第二次检查。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM