Finding the symmetric difference between two arrays
To achieve expected result, use below option by making few changes to your code
- Return count for countInArray (currently it returns undefined)
function countInArray(array, what) {
var count = 0;
for (var i = 0; i < array.length; i++) {
if (array[i] === what) {
count++;
}
}
return count
}
- Remove calling countInArray inside countInArray method
- Run For Loop for tempArr to compare with other each value of tempArr
for (var j = 0; j < tempArr.length; j++) {
if (countInArray(tempArr, tempArr[j]) < 2) {
newArr.push(tempArr[j]);
}
}
Working code :
function diffArray(arr1, arr2) { let tempArr = arr1.concat(arr2); let newArr = []; function countInArray(array, what) { var count = 0; for (var i = 0; i < array.length; i++) { if (array[i] === what) { count++; } } return count} for (var j = 0; j < tempArr.length; j++) { if (countInArray(tempArr, tempArr[j]) < 2) { newArr.push(tempArr[j]); } }
return newArr;}
let arr1 = ["diorite", "andesite", "grass", "dirt", "pink wool", "dead shrub"]let arr2 = ["diorite", "andesite", "grass", "dirt", "dead shrub"]console.log(diffArray(arr1, arr2))
let arr3 = [1, "calf", 3, "piglet"]let arr4 = [7, "filly"]console.log(diffArray(arr3, arr4))
Comparing 2 arrays for differences (find symmetric difference)
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.
The main benefit here is that Set lookup time is constant.
This solution also has space complexity of O(N)
for building the set.
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.
Building the set for the second array gives total space complexity as 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);
Find symmetric difference between two arrays
Here is another idea:
function diffArray(arr1, arr2) {
var newArr = [];
return arr1.filter(function(val) {
return arr2.indexOf(val) === -1;
})
/*the method above, returns a new array, so you can chain it
to concat with the array returned from the filter() method
in the arr2...*/
.concat(arr2.filter(function(val) {
return arr1.indexOf(val) === -1;
}));
}
Trying to solve symmetric difference using Javascript
Here's a version that uses the Set
object to make for faster lookup. Here's the basic logic:
- It puts each array passed as an argument into a separate Set object (to faciliate fast lookup).
- Then, it iterates each passed in array and compares it to the other Set objects (the ones not made from the array being iterated).
- If the item is not found in any of the other Sets, then it is added to the result.
So, it starts with the first array [1, 1, 2, 6]
. Since 1
is not found in either of the other arrays, each of the first two 1
values are added to the result. Then 2
is found in the second set so it is not added to the result. Then 6
is not found in either of the other two sets so it is added to the result. The same process repeats for the second array [2, 3, 5]
where 2
and 3
are found in other Sets, but 5
is not so 5
is added to the result. And, for the last array, only 4
is not found in the other Sets. So, the final result is [1,1,6,5,4]
.
The Set
objects are used for convenience and performance. One could use .indexOf()
to look them up in each array or one could make your own Set-like lookup with a plain object if you didn't want to rely on the Set object. There's also a partial polyfill for the Set object that would work here in this answer.
function symDiff() { var sets = [], result = []; // make copy of arguments into an array var args = Array.prototype.slice.call(arguments, 0); // put each array into a set for easy lookup args.forEach(function(arr) { sets.push(new Set(arr)); }); // now see which elements in each array are unique // e.g. not contained in the other sets args.forEach(function(array, arrayIndex) { // iterate each item in the array array.forEach(function(item) { var found = false; // iterate each set (use a plain for loop so it's easier to break) for (var setIndex = 0; setIndex < sets.length; setIndex++) { // skip the set from our own array if (setIndex !== arrayIndex) { if (sets[setIndex].has(item)) { // if the set has this item found = true; break; } } } if (!found) { result.push(item); } }); }); return result;}
var r = symDiff([1, 1, 2, 6], [2, 3, 5], [2, 3, 4]);log(r);
function log(x) { var d = document.createElement("div"); d.textContent = JSON.stringify(x); document.body.appendChild(d);}
Find Symmetric difference of multi-dimensional and a single-dimensional arrays
This shows how to perform a disjunctive union on two arrays, one being single dimensional while the other is a multidimensional array.
The symmetry is determined by each element of the single with the first element of each sub-array in the multi. The multi will only be one level deep.
Uses: Array.prototype.map(), Array.prototype.filter()
Steps:
- Map over the first input array
- For each element, filter the second input to exclude those found in first input
- Limit results to only the first array returned
Notes:
o
is the iteration ofarray1
t
is iteration ofarray2
t[0]
represents the match keyt[idx]
represents the current value of the sub-array being iterated- Results from array2 will produce a multidimensional array
const array1 = [1, 4, 6, 7];
const array2 = [[1, "more", 12],[8, "some", 12], [7, 3, 9], [2, 7, 5, 4], [4, 3]];
const oneToTwo = array2.map((t, idx) => array1.filter(o => t[idx] !== o))[0]
const twoToOne = array1.map(o => array2.filter(t => o !== t[0]))[0]
console.log(oneToTwo);
console.log(twoToOne)
For two arrays find items that are present in one array only (symmetric difference)
Your approach iterates the first array and because of using map
along with the check for the value, you get undefined for every element of arr1
.
If you take filter
and the other array as well, you could get the wanted result.
function diffArray(arr1, arr2) {
return [
...arr1.filter(elem1 => arr2.every(elem2 => elem2 != elem1)),
...arr2.filter(elem1 => arr1.every(elem2 => elem2 != elem1))
];
}
console.log(diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5]));
Finding the symmetric difference in a loop
You're iterating with i
from 0
to arr.length - 1
. arr[i + 1]
is arr[arr.length]
in the last iteration. It's out of bounds. You could change the loop condition to i < arr.length - 1
.
Example:
function test(...arr) {
let accumulator;
for (let i = 0; i < arr.length - 1; i++) {
let common = arr[i].filter(a => arr[i + 1].includes(a))
let arr0 = arr[i].filter(a => !common.includes(a))
let arr1 = arr[i + 1].filter(a => !common.includes(a))
let merged = [...arr0, ...arr1]
accumulator = merged
}
return accumulator
}
console.log(test([1, 2, 3], [3, 4, 2], [1, 5, 3]))
Related Topics
How to Redirect Url After Login Successful Via Ajax Call in PHP
How to Show a Confirm Message Before Delete
Javascript Regex Splitting Words in a Comma Separated String
Blob Download Is Not Working in Ie
How to Combine First Name and Last Name in JavaScript
Vuejs Error, Invalid Prop: Type Check Failed for Prop. Expected Date, Got Number With Value
Ios Safari/Chrome - Unwanted Scrolling When Focusing an Input Inside the Modal
Javascript - How to Remove All Extra Spacing Between Words
How to Disable Button After (Click) in Angular
How to Display the Entire Object in Console in React Native
How to Add Button on Each Row in Datatable
How to Refresh Specific Div Using Javascript/Jquery With the Variables on It
Refresh Leaflet Map: Map Container Is Already Initialized
How to Take Screenshot of a Div With JavaScript
Chrome Blank Pdf Print Preview