Symmetric wiki difference
We need to find the symmetric difference of the arrays.
I wrote a function for comparing two arrays, in which I combine arrays into one and look for duplicate values ​​in a loop. When finding delete.

function sym() { var args = Array.prototype.slice.call(arguments); var result = compareTwoArray(arguments[0], arguments[1]); if (arguments.length > 2) { for (var i = 2; i < arguments.length; i++) { // console.log('result = ' + result); result = compareTwoArray(result, arguments[i]); } } return result; } function compareTwoArray() { var args = Array.prototype.slice.call(arguments); var result = []; var newArr = args.reduce(function(prev, curr) { return prev.concat(curr); }) for (var i = 0; i < newArr.length; i++) { var count = 0; for (var j = i+1; j < newArr.length; j++) { if (newArr[i] === newArr[j]) { count += 1; newArr.splice(j, 1); j -= 1; } } if (count === 0) { result.push(newArr[i]); } } return result; } console.log(sym([1, 2, 3], [3, 1, 5])); // [2, 5] console.log(sym([1, 1, 3], [4, 6])); // [1, 3, 4, 6] console.log(sym([1, 1, 2, 5], [2, 2, 3, 5])); // [1, 3] console.log(sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5])); // [1, 4, 5] console.log(sym([1, 2, 5], [2, 3, 5], [3, 4, 5])); // [1, 4, 5] 

I do not know how to handle duplicate values.
In one case, it must be removed.

 [1, 2, 3] [3, 1, 5] [2, 5] - Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒΡΡ [2, 5] - получаСтся с ΠΌΠΎΠΈΠΌ ΠΊΠΎΠ΄ΠΎΠΌ 

In the other leave.

 [1, 1, 3] [4, 6] [1, 3, 4, 6] - Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒΡΡ [3, 4, 6] - получаСтся с ΠΌΠΎΠΈΠΌ ΠΊΠΎΠ΄ΠΎΠΌ 

In the other and leave (1) and delete (2).

 [1, 1, 2, 5] [2, 2, 3, 5] [1, 3] - Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒΡΡ [3] - получаСтся с ΠΌΠΎΠΈΠΌ ΠΊΠΎΠ΄ΠΎΠΌ 
  • and how should this work for three or more arrays? for example, what answer is expected with: console.log(sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5])); - Grundy
  • @Grundy in the text of the question there are after all the answers. The symmetric difference reminds me of XOR in the algebra of logic. - tutankhamun
  • Answer [1, 4, 5]. Works: take the first two arrays, delete intersecting numbers [1, 1, 2, 5], [2, 2, 3, 5] => [1, 3] . We get a new array and compare it with the following array [1, 3], [3, 4, 5, 5] => [1, 4, 5] . I have two functions in the code compareTwoArray() for comparison and sym() for returning the answer, in the case of arrays> 2, it is called in the cycle compareTwoArray() , where result return from the previous value, and arguments[i] next array. - stackanon
  • @stackanon, why [1,4,5] and not [1,1,4,5,5] ? - Grundy
  • @Grundy repeating elements in one array should be reduced to one element - stackanon

4 answers 4

Solution for two arrays. Although 3 or more arrays can be processed in steps: first the first two, then the result of the first processing and the third array, and so on.

 function sum(arr1, arr2) { var tmp = arr1.concat(arr2), result = [], value, sum; for (var i = 0; i < tmp.length; i++) { var value = tmp[i]; if (result.indexOf(value) == -1) { sum = 0; if (arr1.indexOf(value) != -1) { sum++; } if (arr2.indexOf(value) != -1) { sum++; } if (sum == 1) { result.push(value); } } } return result; } console.log(sum([1, 2, 3], [3, 1, 5])); // [2, 5] console.log(sum([1, 1, 3], [4, 6])); // [1, 3, 4, 6] console.log(sum([1, 1, 2, 5], [2, 2, 3, 5])); // [1, 3] 

    In javascript, there is a class Set , which in this case can be used as a set, as a result, the record is obtained almost according to the formula

    enter image description here

    In the example below, the spread operator was used , and the rest parameters

     function sym(...arrs) { return arrs.reduce((acc, arr, i) => { var accSet = new Set(acc), // мноТСство ΠΈΠ· элСмСнтов ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ массива arrSet = new Set(arr); // мноТСство ΠΈΠ· элСмСнтов Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ массива return [...accSet].filter(a => !arrSet.has(a)) // элСмСнты ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ мноТСства Π±Π΅Π· элСмСнто Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ .concat( // объСдинСниС [...arrSet].filter(a => !accSet.has(a)) // элСмСнты Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ мноТСства Π±Π΅Π· элСмСнтов ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ ); }, []); } console.log(sym([1, 2, 3], [3, 1, 5])); // [2, 5] console.log(sym([1, 1, 3], [4, 6])); // [1, 3, 4, 6] console.log(sym([1, 1, 2, 5], [2, 2, 3, 5])); // [1, 3] console.log(sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5])); // [1, 4, 5] console.log(sym([1, 2, 5], [2, 3, 5], [3, 4, 5])); // [1, 4, 5] 

    • one
      Gorgeous, as always :) Only if it is in the browser, it should not be very new (and if it’s completely old, my decision will not work) - tutankhamun
    • @tutankhamun, did not quite understand the last sentence :-) - Grundy
    • Well, all this syntactic beauty does not work in all browsers (and rest, as I have looked, generally only in Firefox) - tutankhamun
    • @tutankhamun, works fine in chrome, even in EDGE it works. But in IE, even the last one, it really does not work - Grundy

    Alternatively, you can still do this:

     function sym() { var diff = []; // ДопускаСм, Ρ‡Ρ‚ΠΎ симмСтричная Ρ€Π°Π·Π½ΠΎΡΡ‚ΡŒ пустого массива - пустой массив, // Π° симмСтричная Ρ€Π°Π·Π½ΠΎΡΡ‚ΡŒ ΠΎΠ΄Π½ΠΎΠ³ΠΎ массива - Ρ€Π°Π·Π½ΠΎΡΡ‚ΡŒ пустого массива // ΠΈ этого массива Ρ€Π°Π²Π½Π° самому этому массиву. // Π’Π°ΠΊΠΆΠ΅ симмСтричСская Ρ€Π°Π·Π½ΠΎΡΡ‚ΡŒ Ρ€Π°Π²Π½Π° объСдинСнию минус пСрСсСчСниС, // поэтому... [].forEach.call(arguments, function(arg) { var sum = diff.concat(arg); // ...объСдиняСм массивы... diff = sum.filter(function(item) { // ...оставляСм Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚Π΅ элСмСнты, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½Ρ‹ хотя Π±Ρ‹ // Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΈΠ· массивов... return (-1 === arg.indexOf(item) || -1 === diff.indexOf(item)); }); }); // ...Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ элСмСнты // (ΠΈΠ½Π°Ρ‡Π΅ sym([1, 1, 2, 5], [2, 2, 3, 5]) Π±ΡƒΠ΄Π΅Ρ‚ [1, 1, 3]) return diff.filter(function(item, index, self) { return self.indexOf(item) === index; }); } console.log(sym()); console.log(sym([1, 2, 3])); console.log(sym([1, 2, 3], [3, 1, 5])); console.log(sym([1, 1, 3], [4, 6])); console.log(sym([1, 1, 2, 5], [2, 2, 3, 5])); console.log(sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5])); console.log(sym([1, 2, 5], [2, 3, 5], [3, 4, 5])); 

    • For console.log(sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5])); returned [ 1, 4, 5 ] And for the last example is similar. - Visman
    • @Visman Well, sort of the author of this question, and sought - tutankhamun
    • @Visman and, by the way, your version gives the same result if you execute console.log(sum(sum([1, 1, 2, 5], [2, 2, 3, 5]), [3, 4, 5, 5])); - tutankhamun
    • My function is calculated for two arrays, how did you check it with 3 arrays? Hmmm, I seem confused :) - Visman
    • @Visman as you indicated "the result of the first processing and 3 array" that is sum(sum([1, 1, 2, 5], [2, 2, 3, 5]), [3, 4, 5, 5]) :) - tutankhamun

    Based on the description:

    Symmetric difference of two sets

    Here is an example for two sets (I think you will guess how to screw more sets):

     function getDiff(a, b){ let result = [], pointer = -1; if(!Array.isArray(a) || !Array.isArray(b)) throw new Error(`Both arguments must be arrays!`); a.forEach(e => { if((pointer = b.indexOf(e)) !== -1) b.splice(pointer, 1); else if(result.indexOf(e) === -1) result.push(e); }); b.forEach(e => { if((pointer = a.indexOf(e)) !== -1) a.splice(pointer, 1); else if(result.indexOf(e) === -1) result.push(e); }); return result; } // ΠŸΡ€ΠΈΠΌΠ΅Ρ€ с Π²ΠΈΠΊΠΈ console.info(getDiff([1, 2, 3, 4, 5], [3, 4, 5, 6, 7])); // Π’Π°ΡˆΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ console.info(getDiff([1, 2, 3], [3, 1, 5])); console.info(getDiff([1, 1, 3], [4, 6])); console.info(getDiff([1, 1, 2, 5], [2, 2, 3, 5]));