简体   繁体   English

比较2个数组的差异(找到对称差异)

[英]Comparing 2 arrays for differences (find symmetric difference)

This should be a simple algorithm but I can't wrap my head around the logic. 这应该是一个简单的算法,但我无法绕过逻辑。 I need to take 2 arrays and keep only the values that are found in one array or the other and not both. 我需要使用2个数组并仅保留在一个数组或另一个数组中找到的值,而不是两者。

For example if I have 例如,如果我有

arr1 [1,2,3,6]

arr2 [2,3,4,5,7]

I want to have 2 arrays again being 我想再次拥​​有2个阵列

arr1 [1,6]
arr2 [4,5,7]

EDIT: 编辑:

I removed my old code and put in some other working code. 我删除了旧代码并添加了一些其他工作代码。 Still not very pretty but at least working. 仍然不是很漂亮,但至少工作。 All I would need to do is store arr3 into arr1 and arr4 into arr2. 我需要做的就是将arr3存储到arr1,将arr4存储到arr2中。

    var arr3 = [];
    var arr4 = [];

    var foundMatch = false;

    //find all arr1 elements that don't match arr2 elements
    //store into arr4
    for(var i=0; i<arr1.length; i++)
    {
        foundMatch = false;
        for(var j=0; j<arr2.length; j++)
        {
            if(arr1[i] == arr2[j])
            {
                console.log("match found for [%s] [%s]", i, j);
                foundMatch = true;
                break;
            }
        }
        if(!foundMatch)
        {
            arr4.push(arr1[i]);
        }
    }

    //find all arr2 elements not in arr1
    //store in arr3
    for(var i=0; i<arr2.length; i++)
    {
        foundMatch = false;
        for(var j=0; j<arr1.length; j++)
        {
            if(arr2[i] == arr1[j])
            {
                console.log("match found for [%s] [%s]", i, j);
                foundMatch = true;
                break;
            }
        }
        if(!foundMatch)
        {
            arr3.push(arr2[i]);
        }
    }

You're trying to get A - B and B - A for your 2 sets A and B 你试图为你的2套AB获得A - BB - A

 arr1 = [1,2,3,6] arr2 = [2,3,4,5,7] var required1 = arr1.filter((x) => arr2.indexOf(x) < 0) var required2 = arr2.filter((x) => arr1.indexOf(x) < 0) console.log(required1, required2); 

The fastest solution in terms of time complexity is to create a Set or a hash from one array -> O(N) , then iterate through the other to compare if an element is not the set -> O(M) -> and then add it to the diffs array. 时间复杂度方面最快的解决方案是从一个数组创建一个Set或一个hash - > O(N) ,然后迭代另一个数组来比较一个元素是不是集合 - > O(M) - >然后将它添加到diffs数组。 The main benefit here is that Set lookup time is constant. 这里的主要好处是Set查找时间是不变的。 This solution also has space complexity of O(N) for building the set. 该解决方案还具有用于构建集合的空间复杂度O(N)

You can repeat this for the other array as well, giving you total of O(N) + O(M) + O(N) + O(M) which, when constant factors are removed, is just O(N+M) time complexity. 你可以为另一个数组重复这个,给你总O(N) + O(M) + O(N) + O(M) ,当去除常数因子时,它只是O(N+M)时间复杂性。

Building the set for the second array gives total space complexity as O(N+M) . 为第二个数组构建集合可使总空间复杂度为O(N+M)

 // Total complexity // Time: O(N+M) // Space: O(N+M) // time complexities for each step shown bellow let N = [1,2,3,6] let M = [2,3,4,5,7] const setForN = new Set(N); // O(N) const setForM = new Set(M); // O(M) // O(N + M) at this point const answerN = N.filter(n => !setForM.has(n)) // O(N) const answerM = M.filter(m => !setForN.has(m)) // O(M) // O(N + M) + O(N + M) at this point, which is just O(N + M) console.log(answerN, answerM); 

ES5 solution: ES5解决方案:

 var N = [1,2,3,6] var M = [2,3,4,5,7] var setOfNumbers = function(arr) { return arr.reduce(function(set, item) { return Object.defineProperty(set, item, { value: item }); }, Object.create(null)); } var setForN = setOfNumbers(N); var setForM = setOfNumbers(M); var answerN = N.filter(function(n) { return typeof setForM[n] !== 'number' }); var answerM = M.filter(function(m) { return typeof setForN[m] !== 'number' }); console.log(answerN, answerM); 


Another way is to do what other answers suggest which is to, for each element in N -> O(N) , check if it exists in M -> O(M) , and add it to the diffs array. 另一种方法是做其他答案所建议的,对于N - > O(N)每个元素,检查它是否存在于M - > O(M) ,并将其添加到diffs数组中。 Repeat for the other array. 重复其他数组。

This has better, constant, space complexity O(1) but slower quadratic O(N*M) time. 这具有更好,恒定的空间复杂度O(1)但是更慢的二次O(N*M)时间。

 // Total Complexity: // Time: O(N*M) // Space: O(1) let N = [1,2,3,6] let M = [2,3,4,5,7] // For every element in N -> O(N) // Iterate through M and check if it's there -> O(M) // Total: O(N*M) const answerN = N.filter(n => !M.includes(n)); // For every element in M -> O(M) // Iterate through N and check if it's there -> O(N) // Total: O(M*N) const answerM = M.filter(m => !N.includes(m)); // O(N*M) + O(M*N) at this point, which is just O(N*M) console.log(answerN, answerM); 

You can you the array filter method to check for intersection of 2 arrays: Consider the following code which create 2 new arrays that only contain unique values: 你可以使用数组过滤器方法来检查2个数组的交集:考虑以下代码,它创建2个只包含唯一值的新数组:

let arr1 = [1,2,3,6];
let arr2 =  [2,3,4,5,7];

let newArr1 = arr1.filter((itm)=>{
    return arr2.indexOf(itm) == -1
});

let newArr2 = arr2.filter((itm)=>{
    return arr1.indexOf(itm) == -1
});

Optout of newArr1 and newArr2 are : 选择newArr1和newArr2是:

[1, 6] 
[4, 5, 7]
var arr1 = [1,2,3,6],

    arr1Copy = arr1,

    arr2 = [2,3,4,5,7];

arr1 = arr1.filter(function(outerItem){
  return !arr2.some(function(innerItem){
    return outerItem === innerItem;
  })
})

arr2 = arr2.filter(function(outerItem){
  return !arr1Copy.some(function(innerItem){
    return outerItem === innerItem;
  })
})

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

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