First, reduce() the array of arrays, concatenating a.filter() with b.filter().
Loop through the final array and splice() out any duplicate values.
function sym(...args) {
let reduced = args.reduce((a, b) => a
.filter(item => !b.includes(item))
.concat(b.filter(item => !a.includes(item))));
for (let item of reduced) {
while (reduced.indexOf(item) !== reduced.lastIndexOf(item)) {
reduced.splice(reduced.indexOf(item), 1);
}
}
return reduced;
}
Is there a better, more elegant way to get rid of [or exclude altogether from the beginning] the repeated values, without needing the second step of looping through the array?
function sym(...args) {
let reduced = args
.map(subArr => [...new Set(subArr)])
.reduce((a, b) => a
.filter(item => !b.includes(item))
.concat(b.filter(item => !a.includes(item))));
return reduced;
}
I tried all of the following:
Use filter() at the very end, and filter(item => reduced.indexOf(item) !== reduced.lastIndexOf(item) but it wasn’t recognizing the variables reduced, a, or b.
In the filtering of a and b in the second line, I tried to filter(item => !b.includes(item) && a[a.indexOf(item)] !== a[a.lastIndexOf(item)], but for some reason this was filtering out both 3’s in the array [1, 2, 3, 3], when I expected it to filter out the first, but not the second. I am guessing that the filter() method doesn’t filter / mutate the array one item at a time, but applies the callback to all of the items first, and then once it’s done that, it filters out all the ones that returned true in one, fell swoop.
In the second step, I tried to filter(item => !b.includes(item) && item !== a[a.indexOf(item) + 1]. This didn’t work, either. I feel like this one should’ve worked.