【问题标题】:replace items which appear in both arrays in javascript替换出现在javascript中两个数组中的项目
【发布时间】:2010-07-06 17:06:29
【问题描述】:

我有两个数组,想从一个数组中删除另一个数组中存在的所有元素。

  • 这可以用原生 JS 完成吗?
  • 有 jQuery 函数来做吗?
  • 这样做的最佳做法是什么( 越快越好)

p.s.:也可以用其他语言发布代码,也许我可以将其移植到 Javascript

更新,在接受回答后帮助 JS 帅哥 ;-)

// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
    var 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;
}

(还有一个名为 contains 的原生 JS 方法,但应该可以)

【问题讨论】:

  • 替换成什么?你想合并它们吗?
  • @galam 他想让 A 和 B 不相交,让 A 保持不变。
  • 对不起我的错*displace
  • 现在我真的不明白你的意思。您的意思是“删除”以便 A 中的项目不会像 @glowcoder 建议的那样出现在 B 中吗?
  • 我的英语太糟糕了。删除是正确的。对此感到抱歉。在几分钟内试用@glowcoders 解决方案...

标签: javascript jquery arrays


【解决方案1】:

给定两个集合 a 和 b,从 b 中删除 a 中存在的所有元素。数组格式的翻译和 javascript 留给读者作为练习。排序数组存在优化。

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

【讨论】:

  • 在 JS 中不能使用这种语法,但想法很清楚。我认为这不是很快。 contains() 和 remove() 方法每次都必须遍历所有项目......或者我绝对错了吗?
  • 这个想法是采用伪代码并应用于任何语言。包含是必要的,并且是 O(n)。可以通过使用二级结构(想到 ArrayList-esque)来构建新的 B 数组并向其中添加元素而不是删除来优化删除。我不是 Javascript 人,我不知道此类操作存在哪些机制。
【解决方案2】:
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]

【讨论】:

    【解决方案3】:

    [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 );
    ​
    

    【讨论】:

      【解决方案4】:

      我必须编写一个代码,其中 Ajax 调用将返回一个数组,其中包含必须从本地(客户端)数组中删除的元素列表。

      我以这种方式结束了它:

      // 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;
          });
      });
      

      编辑: 为了使它跨浏览器(我在这里谈论的是IE)。您将必须定义一些和过滤功能。只需将其放在代码中的某个位置即可:

      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;
        };
      }
      

      【讨论】:

      • 不错但不幸的是跨浏览器:(
      • 它是跨浏览器的。但如果客户端使用的是 IE,则必须定义 some 和 filter 方法
      猜你喜欢
      • 2020-08-02
      • 1970-01-01
      • 2016-01-13
      • 2019-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-14
      • 2011-08-20
      相关资源
      最近更新 更多