2

I'd like to find the symmetric difference between TWO arrays. This implementation works, however I'd like to write a function that is specific to only two arrays, rather than one that finds the symmetric difference between a bunch of arrays. The function should like this:

function diffArray(arr1, arr2) { }

then return a new array with the symmetric difference.

My best attempt so far was

var newArr = [];
    for (var i = 0; i < arr1.length; i++){
      var x = arr[i]; 
    for (var n = 0; n < arr2.length; n++){
      var y = arr2[n];
      if (y === x){
        break;
       } else {
      newArr.push(y);
    }
  }
 }

However, I know this is not even close. The question (it is an algorithm problem for FreeCodeCamp) hints to use the methods array.filter(), array.indexOf(), array.concat(), array.slice() in the implementation. I understand that the general idea is to take each element in one of the arrays (the first one in my case), then compare it to every element in the second array. If no matches are found, push that element into the newArr.

Can anyone help with a sound implementation that uses the aforementioned methods and provide a solid explanation/comments on how it works?

Thank you!

Community
  • 1
  • 1
vince
  • 7,808
  • 3
  • 34
  • 41

4 Answers4

3

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;
        }));
}
pacholik
  • 8,607
  • 9
  • 43
  • 55
GuilloteL
  • 112
  • 1
  • 5
2

This is my simple solution

function diffArray(a, b){
c = a.concat(b)
d = [];
var diffarr = c.filter(function(c1){
   if (a.indexOf(c1) === -1 || b.indexOf(c1) === -1){
        d.push(c1)
   }
})
return d;}

diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5]);

Praveen Kumar
  • 161
  • 1
  • 6
1

Alright. I solved it, but I think it can still be done better.

function diffArray(arr1, arr2) {
  var newArray = [];

  function inArray2(value){
      if(arr2.indexOf(value) == -1){
        return true;
      }
    return false;
  }

  function inArray1(value){
    if(arr1.indexOf(value) == -1){
      return true;
    }
    return false;
  }

  var arr1Filtered = arr1.filter(inArray2);
  var arr2Filtered = arr2.filter(inArray1);

  newArray = arr1Filtered.concat(arr2Filtered);
  return newArray;
}

Since this passed all the test cases, I assume it is correct for all cases. Whew.

UPDATE: New and improved algorithm, thanks to helpful input from torazaburo. Hope this helps anyone who is also stuck on this challenge.

function diffArray(arr1, arr2) {
   var newArray = [];

   function notInArray2(value){
       return arr2.indexOf(value) === -1;
   }
   function notInArray1(value){
     return arr1.indexOf(value) === -1;
   }

   var arr1Filtered = arr1.filter(notInArray2);
   var arr2Filtered = arr2.filter(notInArray1);

   newArray = arr1Filtered.concat(arr2Filtered);
   return newArray;
}
vince
  • 7,808
  • 3
  • 34
  • 41
  • Shouldn't `inArray1` be named `notInArray1`? Also, you can just say `return arr1.indexOf(value) === -1;`. –  Oct 25 '16 at 03:09
0

This can be solved by combining multiple array methods.

Below solution uses concat, reduce and includes.

function arrayDifference(arr1, arr2) {
  return arr1
    .concat(arr2)
    .filter(item => !arr1.includes(item) || !arr2.includes(item));
}

console.log(arrayDifference([1, 2, 5], [1, 2, 3, 4, 5, 4])) // [3, 4, 4]
console.log(arrayDifference([1, 2, 5, 4], [1, 2, 3, 4]))    // [5, 3]
Avadhut Thorat
  • 997
  • 11
  • 7