replace items which appear in both arrays in javascript
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;
};
}
精彩评论