Symmetric Difference hint

I’m really starting to hit a wall with the alogrithims. Working on symmetric difference right now. What I feel I need is to use filter to find the unique array values. So far I have

function sym(args) {
  
var myArr = [];
  
  myArr += arguments[0].filter(function (val) {
    return arguments[1].indexOf(val) == -1;
  });
  
  return myArr; 
  
}

sym([1, 2, 3], [5, 2]);

Which throws out a type error that arguments[1].indexOf is not a function. I’m not really sure why this doesn’t work. Assuming I can fix it I would then have to run it a second time comparing arguments[1] to [0]. Any hints on this?

Pull the arguments into variable(s) before attempting to filter. arguments refers to the arguments object of the current scope. That means that inside your filter callback function, arguments refers to the arguments of that function (the value of the element, the index of the element, and the Array object).

1 Like

eg var arrA = arguments[0], arrB = arguments[1] … best to do with a for loop as you will have different size arguments for(… ) myArry.push(arguments[x])
you will then have an array containing 2…3…4 arrays depending on the problem

then next step clear duplicates in arrays eg if arry is like this [2,2,3,4] or [2,2,2,3,4] these will mess you up so need to remove duplicates

this can be done in the for loop (i did it in for loop) i used the new set method from javascript ES6
basically if you create a set from an array it removes duplicates … then you convert set to array and bingo you have array of unique entrys

finally you compare using for loop …first array to second array eg myArry[0][1,2,3] myArr[1][5,2] … i used filter() and used includes() method in the filter … basically if myArry[0] includes(5) i splice it out of myArr[0] else i push() it to myArr[0] … end up with myArr[1,3,5] then if you have another array eg myArr[2] you check myArr[0] to myArr[2] so if myArr[2] = [1,4,5] it would be
myArr[1,3,5] myArr[2] = [1,4,5] splice out 1 push 4 splice 5 leaving myArr[1] = [3,4]

hope that helps as im rushing out of work now … finished for the day

@ArielLeslie @JohnL3 Thank you both, I did not know this about the arguments object but that makes a lot of sense now!

John I’ve only read half your response as I’m going to try and stumble forward on my own. I will definitely check up if I get stuck again or compare my final answer to yours. Many thanks!

I think I’m closing in on something! I have

function sym(args) {
  
  var myArr = arguments[0];
  var myArgs = [];

  for (var i=1; i<arguments.length; i++) {
    myArgs.push(arguments[i]);
  }
   
  for (var k=0; k<myArgs.length; k++) {
    for (var l=0; l<myArgs[k].length; l++) {
    
      if (myArr.indexOf(myArgs[k][l]) == -1) {
        myArr.push(myArgs[k][l]);
    }
      else {
        myArr.filter(function(val) {
          return val !== myArgs[k][l];
        });
      }
  }
}
return myArr;
}

sym([1, 2], [2, 3]);

And the trouble I’m having is at line 17 with filter. I believe my code isn’t working as filter does not alter the original array. Correct? In which case what method is available in order to replace that line with something that can remove an item by value from my original array? (I’ve considered .slice for this but I don’t think it’ll work as that is based on position and not value.

Update: I was wrong, splice works just fine.

      else {
        myArr.splice(myArr.indexOf(myArgs[k][l]),1);
      }

The missing piece of the puzzle is dealing with the arguments that have duplicate values. For my current code to work I need to find an easy way to remove the duplicates.

Remember that you can always do

someArray = someArray.filter(function(val){
    //whatever
});
1 Like

I’m so close now, but this is driving me nuts!

function sym(args) {
  
  var myArr = arguments[0];
  var myArgs = [];

  for (var i=1; i<arguments.length; i++) {
    myArgs.push(arguments[i]);
  }
 
   
  for (var k=0; k<myArgs.length; k++) {
    for (var l=0; l<myArgs[k].length; l++) {
    
      if (myArr.indexOf(myArgs[k][l]) == -1) {
        myArr.push(myArgs[k][l]);
    }
      else {
        myArr.splice(myArr.indexOf(myArgs[k][l]),1);
      }
  }
} 
return myArr;
}

sym([1, 2], [3, 2, 2]);

With this example it should return [1,3] I’m returned with [1,3,2] because my else statement only removes the 2 from the main array. As a second 2 is in the arguments, and now the main array does not have one it’s added back in.

I need to remove all instances of 2 to prevent this. I’ve tried

      else {
        myArr.splice(myArr.indexOf(myArgs[k][l]),1);
        myArgs[k] = myArgs[k].filter(function (val) {
          val !== myArgs[k][l];
        });

But I don’t understand why it doesn’t work.

I figured it out! For anyone else who’s having trouble with this and reading through the thread I’ll post the solution I came up with. It may not be the best, but it does the trick!

function sym(args) {
    var myArr = [];
    var myArgs = [];
    for (var i = 0; i < arguments.length; i++) {
        myArgs.push([]); //CREATE EMPTY ARR TO PUSH INTO
        for (var h = 0; h < arguments[i].length; h++) {
            if (myArgs[i].indexOf(arguments[i][h]) == -1) {
                myArgs[i].push(arguments[i][h]);
            } //THIS CHECKS IF THE VALUE IS IN THE ARR, IF NOT IT GETS PUSHED
        } //PREVENTS DUPLICATES
    }
    myArr = myArgs[0];
    myArgs.shift(); //MOVES FIRST VALUE/ REMOVES FROM ARGS
    for (var k = 0; k < myArgs.length; k++) {
        for (var l = 0; l < myArgs[k].length; l++) {
            if (myArr.indexOf(myArgs[k][l]) == -1) {
                myArr.push(myArgs[k][l]);
            } //IF THE VALUE OF ARG NOT IN MYARR IT GETS PUSHED IN
            else {
                myArr.splice(myArr.indexOf(myArgs[k][l]), 1);
            } //ELSE IT GETS REMOVED FROM MYARR
        }
    }
    return myArr;
}
sym([1, 2], [2, 3]);

well done … great to see you got it working …

1 Like