2016-11-16 10 views
0

Ich habe eine Funktion zur Berechnung der symmetrischen Differenz zwischen Arrays, die als Argumente übergeben wurden, gemacht. Ich habe es für zwei Arrays gemacht und es hat funktioniert. Das Problem ist jetzt, dass ich die Funktion auf n Variablen erweitern möchte. Ich denke, dass ich die Symm-Differenz berechnen sollte, wenn die Argumente.Länge der Funktion gleich zwei ist, sonst sollte ich eine rekursive Funktion aufrufen, um die Symm Diff zwischen den anderen Elementen und den ersten beiden zu berechnen? Ich weiß nicht, ich bin sehr verwirrt.Rekursive Funktion für symmetrische Differenz

function sym(args) { 

    var arr=[].slice.call(arguments); 
    var cnts={}; 
    var result=[]; 

    if(arguments.length==2){ 

    arr=arguments[0].concat(arguments[1]); 
    console.log(arr); 
    for(var number in arr){ 

     if(cnts.hasOwnProperty(arr[number])){ 

     ++cnts[arr[number]].cnt; 

     } 

     else cnts[arr[number]]={cnt:1,val:arr[number]}; 

    } 

    for(var counts in cnts){ 

     if(cnts[counts].cnt===1) result.push(cnts[counts].val); 

     } 

    } 

    else{ 

     var first=arguments[0]; 
     var nextDiff=function(next){ 

     return ...........?????????; 

     }; 

    } 

    return result; 
} 

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

Mögliche Duplikat [Der Versuch, symmetrische Differenz mit Javascript zu lösen] (http://stackoverflow.com/questions/30834946/trying-to-solve-symmetric-difference-using-javascript) –

Antwort

2

Hier gibt es zwei wichtige Einsichten. Die erste ist, dass wir haben

sym_diff(A1, A2, ..., An) === sym_diff(sym_diff(A1, A2), A3, ..., An) 

Dies folgt aus der Tatsache, dass symmetrische Differenz assoziativ ist und uns ermöglicht, zu wiederholen.

Die zweite ist, dass

sym_diff(A, B) === diff(A, B) ++ diff(B, A) 

wo ++ hier bedeutet Vereinigung und diff ist die übliche relative Differenz.

Daraus folgt:

function sym_diff() { 
    // Convert the passed arguments to an array for convenience 
    let args = Array.prototype.slice.call(arguments); 

    // This is an example of an immediately-invoked function expression 
    // (IIFE). Basically, we define a function and then immediately call it (see * below) 
    // in one go and return the result 

    return (function sym_diff(a, b) { 
     // a: the first argument 
     // b: an array containing the rest of the arguments 

     if (!b.length) { 
      // If only a is given, return a if is an array, undefined otherwise 
      return Array.isArray(a) ? a : undefined; 
     } 
     else if (b.length === 1) { 
      // Define a function that takes two arrays s and t, and returns 
      // those elements of s that are not in t. This is an 
      // example of arrow notation` 
      let diff = (s, t) => s.filter(i => t.indexOf(i) === -1); 

      // Use the second insight to compute the sym_diff of a and 
      // b[0] 
      return diff(a, b[0]).concat(diff(b[0], a)); 
     } 
     else { 
      // Use the first insight to recursively compute the sym_diff 
      // We pass [b[0]] because sym_diff expects an array of arrays as the second argument 
      // b.slice(1) gives all of b except the first element 
      return sym_diff(sym_diff(a, [b[0]]), b.slice(1)); 
     } 
    })(args[0], args.slice(1)); //* Here is where we pass the arguments to the IIFE 
} 
+0

Danke! Kannst du mir mehr über diesen Code erklären? Ich fange an und ich verstehe nicht viel. Zum Beispiel .. was ist b in der sym_diff Aufruf? es braucht alle Argumente außer dem ersten? – Juan

+1

Ich habe dem Code ein paar Kommentare hinzugefügt. Ich hoffe, das hilft. –