Find the Symmetric Difference - can I use filter() here?

Is it possible to use filter on arrays? As in, I want a filter to run on args that are arrays (as opposed to elements IN an array).

This is my code:

function sym(args){

  function nonOverlap(arr1, arr2){
    for(var i = 0; i < arr1.length; i++){
      if(arr2.indexOf(arr1[i]) === -1){
        console.log(arr1[i]);
        return arr1[i];
      }
    }

    for(var j = 0; j < arr2.length; j++){
      if(arr1.indexOf(arr2[j]) === -1){
        console.log(arr2[j]);
        return arr2[j];
      }
    }
  }

  console.log(args.filter(nonOverlap));

}

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

Sure. You can use the arguments object. Arguments object is not an array though, so to use filter() on it you’ll have to convert it to an array first.

1 Like

as @ArtemPetrov said, you’d want to change the parameter signature of your function:

function sym(...arrays){...}

That makes arrays an array of arguments, regardless of whether they’re arrays or strings.

Now, within your nonOverlap(), the first time you encounter a value that is not included in the other array, you’re returning that value. Is that your intent? Are you filtering the arrays specifically for unique values in both?

I added the following:

let argsAsArr = [...arguments];
console.log(argsAsArr);

When I don’t have any other code and run the function on sym([1, 2, 3], [5, 2, 1, 4]); the console logs the following (correctly):

Capture

But for some reason, when I add the remaining code back in, the result of argsAsArr (based on debugging tools) are:

I don’t know why argsAsArr value would change b/c of code being added after it…?

Do you have this as a repl, or a codepen? I have something similar (a function to filter for unique elements in N arrays) that I have as a repl, but I don’t want to take away from your learning experience by just GIVING it to you. :wink:

Just tried it in dev tools and what I see is an array with 2 elements, like in your first screenshot. Hard to say what’s wrong without seeing your full code.

The challenging bit is, you’re wanting to filter with both arrays. In building my repl, here’s the logic I used, just to think differently:

  • First, merge all arrays into a single masterArr. Use the syntax sym(...arraysParam) to store all parameters into an array, then merge them out.
  • Then, write a function (I call it isUnique()). The function will be used in a filter() function, and these have the parameter signature function(arrayMember, index, originalArray). Using this, within my isUnique(), I can filter my originalArray parameter to a list of matching elements. Finally, within isUnique, I return true if there is only one matching element, false for more.
  • Writing the filter function simply gets passed that isUnique.

The beauty of this approach is, I’m only working on a single array. Doesn’t matter if my params are five arrays containing similar values, or one array with duplicates. It simply filters all passed array and returns only unique values.

Not sure if that’s the approach you’re looking for, but it works very very well on my repl

Hi - thanks all for the feedback!

@snowmonkey I’m not sure I understand what sym(...arraysParam) means…can you explain it a little more?

In the meantime, this is my full code:


function sym(args){

  let argsAsArr = [...arguments];
  console.log(argsAsArr);

  function nonOverlap(arr1, arr2){
    for(var i = 0; i < arr1.length; i++){
      if(arr2.indexOf(arr1[i]) === -1){
        console.log(arr1[i]);
        return arr1[i];
      }
    }

    for(var j = 0; j < arr2.length; j++){
      if(arr1.indexOf(arr2[j]) === -1){
        console.log(arr2[j]);
        return arr2[j];
      }
    }
  }

  console.log(argsAsArr.filter(nonOverlap));

}

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

so the sym(...arraysParam) line simply says "spread all the parameters passed to sym, and assign them AS AN ARRAY to arraysParam. It does much the same thing you’re doing with let argsAsArr = [...arguments] does.

Now, you’re code is having a problem, yes? because the .filter() doesn’t recognize arr2. There is no arr1 or arr2, so it won’t be able to do an indexOf, for example.

Yes, you are right in that I made up arr1, arr2 as parms that will go into the function nonOverLap whenever it is invoked. So when it’s invoked, the function will expect 2 arrays. Is that not right…?

But you are right that filter is not recognizing arr2…which I think is related to the screenshot I took above showing the arrays that were created from the arguments of sym(). arguments[1] = 0 for some reason…??

Also, so I can let argsAsArr = […arguments] do the work of converting parms into arrays?