Algorithm to get changes between two arrays

后端 未结 8 1381
难免孤独
难免孤独 2021-02-04 05:43

I needed to create an algorithm which will (efficiently) take an old array and a new array and give me back the changes between the two (which items added, which removed). It ha

8条回答
  •  野的像风
    2021-02-04 06:17

    I created a speed test between two possible implementations.

    Source code:

    function diff1 (o, n) { 
      // deal with empty lists 
      if (o == undefined) o = []; 
      if (n == undefined) n = []; 
    
      // sort both arrays (or this won't work) 
      o.sort(); n.sort(); 
    
      // don't compare if either list is empty 
      if (o.length == 0 || n.length == 0) return {added: n, removed: o}; 
    
      // declare temporary variables 
      var op = 0; var np = 0; 
      var a = []; var r = []; 
    
      // compare arrays and add to add or remove lists 
      while (op < o.length && np < n.length) { 
          if (o[op] < n[np]) { 
              // push to diff? 
              r.push(o[op]); 
              op++; 
          } 
          else if (o[op] > n[np]) { 
              // push to diff? 
              a.push(n[np]); 
              np++; 
          } 
          else { 
              op++;np++; 
          } 
      } 
    
      // add remaining items 
      if( np < n.length ) 
        a = a.concat(n.slice(np, n.length)); 
      if( op < o.length ) 
        r = r.concat(o.slice(op, o.length)); 
    
      return {added: a, removed: r};  
    }
    
    function diff2 (o, n) {
            // convert array items to object members
        var objO = {}, objN = {};
        for (var i = 0; i < o.length; i++) {
            objO[o[i]] = 1;
        }
        for (var i = 0; i < n.length; i++) {
            objN[n[i]] = 1;
        }
    
        var a = []; var r = []; 
    
        for (var i in objO) {
            if (i in objN) {
                delete objN[i];
            }
            else {
                r.push (i);
            }
        }
        for (var i in objN) {
            a.push (i);
        }
        return {added: a, removed: r};
    }
    
    var o = [], n = [];
    for (var i = 0; i < 300000; i++) {
        if (i % 2 == 0) {
            o.push (i);
        }
        if (i % 3 == 0) {
            n.push (i);
        }
    }
    
    var start = new Date ();
    diff1 (o, n);
    var end1 = new Date ();
    diff2 (o, n);
    var end2 = new Date ();
    
    alert ((end1 - start) + ", " + (end2 - end1));
    

    The disadvantage of diff2 that the returned arrays (added, removed) are not sorted.

    Speed Test:

    IE7: diff1: 2578ms, diff2: 1906ms

    IE8: diff1: 1953ms, diff2: 1152ms

    Firefox: diff1: 254ms, diff2: 527ms

    Opera: diff1: 143ms, diff2: 253ms

    Safari: diff1: 466ms, diff2: 657ms

    Chrome: diff1: 734ms, diff2: 581ms

    Conclusion: diff1 is faster in Firefox, Opera and Safari, diff2 is faster in IE and Chrome.

提交回复
热议问题