I am trying to figure out a solution for symmetric difference using javascript that accomplishes the following objectives:
This works for me:
function sym() {
var args = [].slice.call(arguments);
var getSym = function(arr1, arr2) {
return arr1.filter(function(each, idx) {
return arr2.indexOf(each) === -1 && arr1.indexOf(each, idx + 1) === -1;
}).concat(arr2.filter(function(each, idx) {
return arr1.indexOf(each) === -1 && arr2.indexOf(each, idx + 1) === -1;
}));
};
var result = getSym(args[0], args[1]);
var len = args.length - 1, i = 2;
while (--len) {
result = [].concat(getSym(result, args[i]));
i++;
}
return result;
}
console.info(sym([1, 1, 2, 5], [2, 2, 3, 5], [6, 8], [7, 8], [9]));
Pure javascript solution.
function diff(arr1, arr2) {
var arr3= [];
for(var i = 0; i < arr1.length; i++ ){
var unique = true;
for(var j=0; j < arr2.length; j++){
if(arr1[i] == arr2[j]){
unique = false;
break;
}
}
if(unique){
arr3.push(arr1[i]);}
}
return arr3;
}
function symDiff(arr1, arr2){
return diff(arr1,arr2).concat(diff(arr2,arr1));
}
symDiff([1, "calf", 3, "piglet"], [7, "filly"])
//[1, "calf", 3, "piglet", 7, "filly"]
Hey if anyone is interested this is my solution:
function sym (...args) {
let fileteredArgs = [];
let symDiff = [];
args.map(arrayEl =>
fileteredArgs.push(arrayEl.filter((el, key) =>
arrayEl.indexOf(el) === key
)
)
);
fileteredArgs.map(elArr => {
elArr.map(el => {
let index = symDiff.indexOf(el);
if (index === -1) {
symDiff.push(el);
} else {
symDiff.splice(index, 1);
}
});
});
return (symDiff);
}
console.log(sym([1, 2, 3, 3], [5, 2, 1, 4]));
This function removes duplicates because the original concept of symmetric difference operates over sets. In this example, the function operates on the sets this way: ((A △ B) △ C) △ D ...
function sym(...args) {
return args.reduce((old, cur) => {
let oldSet = [...new Set(old)]
let curSet = [...new Set(cur)]
return [
...oldSet.filter(i => !curSet.includes(i)),
...curSet.filter(i => !oldSet.includes(i))
]
})
}
// Running> sym([1, 1, 2, 6], [2, 3, 5], [2, 3, 4])
console.log(sym([1, 1, 2, 6], [2, 3, 5], [2, 3, 4]))
// Return> [1, 6, 5, 2, 4]
My short solution. At the end, I removed duplicates by filter().
function sym() {
var args = Array.prototype.slice.call(arguments);
var almost = args.reduce(function(a,b){
return b.filter(function(i) {return a.indexOf(i) < 0;})
.concat(a.filter(function(i){return b.indexOf(i)<0;}));
});
return almost.filter(function(el, pos){return almost.indexOf(el) == pos;});
}
sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5]);
//Result: [4,5,1]
Just use _.xor or copy lodash code.