[英]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套
A
和B
获得A - B
和B - 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.