Symmetric difference, reduce arguments

Hi! Im making the Symmetric difference challenge. I created a code that resolves the symmetric difference for two arrays, but i don’t know how to use reduce to extend it two several variables.

var args = Array.prototype.slice.call(arguments);

function deleteAll(arr,num) {
    
    arr=arr.filter(function(value){
    
        return (value!==num);
    
     });
  
     return arr;
  
}

function diff(arr1,arr2){
  
    for(var i=0;i<arr1.length;i++){
      
        for(var j=0;j<arr2.length;j++){
            
            if(arr1[i]===arr2[j]) {
                
                arr1=deleteAll(arr1,arr1[i]); 
                 i-=1;
     
             }
        } 
     }  
   
  return arr1;
  
}

function sym(arr1,arr2) {

  return (diff(arr1,arr2).concat(diff(arr2,arr1)));
  
}


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

Could you rephrase what you’re trying to do. I don’t understand:

i don’t know how to use reduce to extend it two several variables.

It looks like your symmetric difference function does what it’s supposed to do.

It works only for two arrays sym(arr1,arr2). But i want that it works for several variables sym(arr1,arr2,arr3). I saw in the algorithms section that i can do with reduce , but i do not know how to do it in my code.

Ah, now I understand. Give this a try:

function sym(arr1,arr2) {
  var args = Array.prototype.slice.call(arguments)
  return args.reduce(function(a,b){
  	return diff(a,b).concat(diff(b,a));
  });
}
1 Like

Thanks! It works but i need to remove repeated elements ?How can i do it?..I have a function called deleteRepeated()…but where should i insert it?

No problem. Using the code you posted initially, I setup this jsfiddle

When you click run you can see it removes repeated elements from the three arrays passed to it.

Is this what you’re looking for?

1 Like

Sorry, no…i want to eliminate de the repeated at the end…

You’re right, and I see the problem.

There isn’t an easy way to adapt your first solution to the problem of more than 2 arrays.

I re-wrote the solution to work with your requirements.

function sym() {
  var args = Array.prototype.slice.call(arguments);
  var flatArgs = args.reduce((a, b) => a.concat(b));
  return flatArgs.filter(function( arrayValue ){
  	j = 0;
  	for (var i = 0; i < arguments.length; i++) {
    	if ( args[i].indexOf( arrayValue ) == -1 ) {
      	j++;
        if ( j == arguments.length - 1 ) {
	      	return arrayValue;
        }
      }
    }
  });
}


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

What happens here is the arguments are pulled into the args array.

Then, the args array is “flattened” into flatArgs array. (all values are concat into one array)

Finally, we run a filter function, which returns only the values that pass the test (reach the return arrayValue statement).

The way the function is written, a value is taken from the flatArgs array and checked against each array passed using indexOf. It’s only returned if .indexOf == -1 each time except once (meaning it only showed up in one of the arrays).

I can’t think of a much different way to solve the problem.

1 Like

Thank you!!!