Find the Symmetric Difference, Discussion of Set Solution

Tell us what’s happening:
Hey all, I was going through the interview prep questions and I’d recently learned about JS sets so I tried using them to solve the Symmetric Difference problem. I eventually got it to work but I’m not quite sure if using sets was a very roundabout way of solving this problem. I was hoping to get some feedback as this is the first time I’ve used a higher order data structure (i.e. not an array or an object).
Was there a way simpler solution? Is my code at all efficient? How do sets (and possibly other similar data structures) affect the efficiency of my code in general?
More importantly, would this fly in an interview?

Your code so far


//helper function that converts an array to a set
function arrToSet(arr){
  const s = new Set();
  arr.forEach(el => s.add(el));
  return s;
}

//helper function that returns the delta of two sets. Delta is returned as a set
function delta(s1, s2){
  s2.forEach(el => {
    if(s1.has(el)){
      s1.delete(el);
    } else {
      s1.add(el);
    }
  });

  return s1;
}

function sym(...args) {
  const arrArgs = Array.from(args);
  //convert all arrays to sets
  const sets = []
  arrArgs.forEach(arg => {
    sets.push(arrToSet(arg));
  });
  //iterate over them taking symmetric differences
  let returnSet = new Set();
  for(let i = 0; i < sets.length; i++){
    returnSet = delta(returnSet, sets[i]);
  }
  //convert the last set into an array
  //return it
  return Array.from(returnSet);
}

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

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36.

Link to the challenge:
https://learn.freecodecamp.org/coding-interview-prep/algorithms/find-the-symmetric-difference

  • new Set([1,2,3,4,5]), ie new Set(anArray), is a much shorter way to write your arrToSet function.
  • you are already using ...args, so const arrArgs = Array.from(args); is redundant: it’s already an array.
  • you can get rid of basically everything before this line and do:
    let returnSet = new Set();
    for(let i = 0; i < args.length; i++){
      returnSet = delta(returnSet, new Set(args[i]));
    }
    
  • minor: because it is has side effects & specifically works with logic you’ve defined in the function, I would move delta inside the main function.
  • maybe minor, but it would improve your code: I would also look at figuring out a way to not reassign that returnSet (and not create a new one every time you iterate in the loop).
  • minor: call the parameter arrays or something rather than args – you know it’s args, but what actually are the arts.

Sets are useful for this kind of thing. They’re useful in general, just not at all as useful as they could be because you generally need to serialise back and forth to arrays to actually use them, which gets painful.

Thanks for your reply!
I actually didn’t know I could pass in an array to the set constructor so I’ll be doing that from now on.
On your point to moving the delta function inside the main function: Do you mean as a closure, or just the logic of the delta function?

Whole function inside because it smells of side-effects, so better to contain those.

Then there isn’t really any point keeping it separate, so you might as well just inline the logic into the loop.

Then at that point you should realise you don’t need to rebuild the Set every time, you can just create returnSet once before the loop, then add/delete from that one instance, which simplifies everything a bit and definitely makes it more efficient.