开发者

replace items which appear in both arrays in javascript

开发者 https://www.devze.com 2023-01-06 09:31 出处:网络
I have two arrays and want to remove from one all elements which exist in the other as well. Can this be done with native JS?

I have two arrays and want to remove from one all elements which exist in the other as well.

  • Can this be done with native JS?
  • Is there a jQuery function to do it?
  • What are best practices to do so (the faster the better)

p.s.: just post code in other languages too, maybe I can port it to Javascript

Update, after accepting answer to help the JS dudes ;-)

// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
    va开发者_运维知识库r rest = this.slice((to || from) + 1 || this.length);
    this.length = from < 0 ? this.length + from : from;
    return this.push.apply(this, rest);
};
// Array Contains - By Helmuth Lammer (TU Vienna)
Array.prototype.contains = function(key){

    for(var i = 0; i<this.length; i++){
        if(this[i]  == key) return i;
    }

    return false;
}

(There is a native JS method named contains too, but it should work)


Given two sets a and b, to remove all elements present in a from b. Translation to array formatting and javascript left as an exercise to the reader. Optimizations exist for sorted arrays.

for(element e : b) {
    if(a.contains(e)) {
         b.remove(e);
    }
}


var foo = [1, 2, 3, 4, 5];

function removeAll(a, b) {
    var i = 0,
        j;

    while (i < b.length) {
        for (j = 0; j < a.length; j++) {
            if (a[j] === b[i]) {
                b.splice(i, 1);
                i--;
                break;
            }
        }
        i++;
    }
}

removeAll([2, 4], foo);
// foo === [1, 3, 5]


[See it in action]

// two arrays
var arr1 = [1,2,3,4,5];
var arr2 = [4,5,6,7,8];

// returns the element's index in an array
// or -1 if there isn't such an element
function indexOf( arr, el ) {
  for ( var i = arr.length; i--; ) {
    if ( arr[i] === el ) return i;
  }
  return -1;
}

// go through array1 and remove all
// elements which is also in array2
​for ( var i = arr1.length; i--; )​ {
  if ( indexOf( arr2, arr1[i] ) !== -1 ) {
    arr1.splice(i, 1);
  }
}

// result should be: arr1 = [1,2,3] 
alert( arr1 );
​


I had to write a code once where an Ajax call would return an array containing a list of element which must be deleted from a local (client-side) array.

I ended implementing it this way:

// The filter method creates a new array with all elements that pass the
// test implemented by the provided function.
local_array = local_array.filter( function (element) {
    // Now I check if this element is present in the "delete" array. In order to do 
    // that I use the "some" method which runs a callback function for each of the
    // array elements and returns true or false.
    return !items_to_delete.some( function(item) {
        return item.pk === element.pk;
    });
});

Edit: In order to make it cross-browser (I am talking about IE here). You will have to define the some and filter functions. Just put this somewhere in your code:

if (!Array.prototype.some)
{
  Array.prototype.some = function(fun /*, thisp*/)
  {
    var i = 0,
        len = this.length >>> 0;

    if (typeof fun != "function")
      throw new TypeError();

    var thisp = arguments[1];
    for (; i < len; i++)
    {
      if (i in this &&
          fun.call(thisp, this[i], i, this))
        return true;
    }

    return false;
  };
}

if (!Array.prototype.filter)
{
  Array.prototype.filter = function(fun /*, thisp*/)
  {
    var len = this.length >>> 0;
    if (typeof fun != "function")
      throw new TypeError();

    var res = [];
    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
      {
        var val = this[i]; // in case fun mutates this
        if (fun.call(thisp, val, i, this))
          res.push(val);
      }
    }

    return res;
  };
}
0

精彩评论

暂无评论...
验证码 换一张
取 消