As chuckadams said, this is the sort of thing .reduce()
is made for. Because .reduce()
is an function you can call on any array, the first this you are going to want to do is get all of the arguments (the number can vary for this challenge) into an array.
Usage is fairly simple: yourArray.reduce(callback)
in this case yourArray would be replaced with the name of the array that has all you arguments (each of which should also be an array).
There are some other arguments you can use with .reduce()
, but that is all you need for this challenge.
Here is a quick explanation of how .reduce()
works (there is more, but again, we donāt need it for this challenge):
.reduce()
takes the first two elements of the array (letās call them previousValue
and currentValue
) and passes them to a callback* function, the callback function is a function you write that should process (in this case compute the symmetric difference) those two elements and then return
a result. The return
ed result is then passed to the callback as āpreviousā along with the third element in the array which is passed as ācurrentā; the result of this is passed to the callback along with the fourth elementā¦ and so on until all of the elements have been passed. This is exactly what you need to do for this challenge, so it fits nicely.
With this in mind, all you need to do is put all arguments in an array and remove all duplicates within a single array (i.e. convert them to sets), write a callback function that computes and returns the symmetric difference of two sets, and then .reduce()
the array with your arguments in it.
*a little more info about callbacks, because they were hard for me to wrap my head around at first. A call back is a function you write, it can either be written directly in the function in which it is called or can be written elsewhere (but within the same scope) and then passed by name to the function:
yourArray.reduce(function(arg1, arg2) { //your function here });
OR
yourArray.reduce(myCallback); ... function myCallback(arg1, arg2) { //your function here }
I personally prefer the second option because it means the callback can also be called by other functions, but that isnāt always necessary. Itās important to note the syntax in the second option, you donāt include the parenthesis or the arguments with your callback when you call reduce (or any function that you pass a callback too) but they are included wherever you actually declare your function, as in my example above.
Finally, here was the solution I came up with if youāre interested:
function removeDupes(arr) {
return arr.filter(function(val,i,self) {
return self.indexOf(val) === i;
});
}
function sym() {
var args = Array.prototype.slice.call(arguments); //this converts the arguments to an array called args
function symDiff(arr1, arr2) {
arr1 = removeDupes(arr1); //these two lines convert the passed arrays to sets by removing duplicates
arr2 = removeDupes(arr2);
var index = 0;
for (var i in arr2) {
index = arr1.indexOf(arr2[i]);
if (index >= 0) {
arr1.splice(index, 1);
}
else arr1.push(arr2[i]);
}
return arr1;
}
return args.reduce(symDiff);
}
sym([1, 2, 3], [5, 2, 1, 4]);