Javascript算法查找数组中不在另一个数组中的元素

时间:2010-06-03 04:14:44

标签: javascript jquery algorithm arrays

我正在寻找一种好的算法来获取一个数组中不是另一个数组中元素的所有元素。所以给定这些数组:

var x = ["a","b","c","t"];
var ​​​​​​​​​y = [​​​​​​​"d","a","t","e","g"];

我想最终得到这个数组:

var z = ["d","e","g"];

我正在使用jquery,因此我可以利用$.each()$.inArray()。这是我提出的解决方案,但似乎应该有更好的方法。

// goal is to get rid of values in y if they exist in x
var x = ["a","b","c","t"];
var y = ["d","a","t","e","g"];

var z = [];
$.each(y, function(idx, value){
  if ($.inArray(value,x) == -1) {
    z.push(value);
  }
});
​alert(z);  // should be ["d","e","g"]

这是code in action。有什么想法吗?

8 个答案:

答案 0 :(得分:49)

使用新的ECMA5 javascript后期回答:

var x = ["a","b","c","t"];
var y = ["d","a","t","e","g"];

myArray = y.filter( function( el ) {
  return x.indexOf( el ) < 0;
});

答案 1 :(得分:17)

ES6中的

只是

const x = ["a", "b", "c", "t"];
const y = ["d", "a", "t", "e", "g"];

console.log( y.filter(e => !x.includes(e)) );

(另一个选项是y.filter(e => x.indexOf(e)===-1)

答案 2 :(得分:12)

以下是使用underscore.js的替代方法:

function inAButNotInB(A, B) {
  return _.filter(A, function (a) {
    return !_.contains(B, a);
  });
}

答案 3 :(得分:11)

var z = $.grep(y, function(el){return $.inArray(el, x) == -1}); 

此外,该方法名称对于自己的好处来说太短了。我希望它的意思是isElementInArray,而不是indexOf。

有关包含对象的演示,请参阅http://jsfiddle.net/xBDz3/6/

答案 4 :(得分:2)

首先制作数组的排序副本。如果顶部元素相等,则将它们都删除。否则,删除较少的元素并将其添加到结果数组中。如果一个数组为空,则将其他数组的其余部分添加到结果中并完成。您可以遍历已排序的数组,而不是删除元素。

// assume x and y are sorted
xi = 0; yi = 0; xc = x.length; yc = y.length;
while ( xi < xc && yi < yc ) {
  if ( x[xi] == y[yi] ) {
    xi += 1;
    yi += 1;
  } else if ( x[xi] < y[yi] ) {
    z.push( x[xi] );
    xi += 1;
  } else {
    z.push( y[yi] );
    yi += 1;
  }
}
// add remainder of x and y to z.  one or both will be empty.

答案 5 :(得分:2)

Maybe jLinq can help you?

它允许您针对javascript对象运行这样的查询。

例如:

var users = [ { name: "jacob", age: 25 },  { name: "bob" , age: 30 }]
var additionalusers = [ { name: "jacob", age: 25 },  { name: "bill" , age: 25 }]

var newusers = jLinq.from(users).except(additionalusers).select();

>>> newusers = [ { name: "bob" , age: 30 } ]

目前对你来说有点矫枉过正,但这是一个我很乐意了解的强大解决方案。

它可以做交叉,联合,处理布尔逻辑和各种伟大的linq风格的善良。

答案 6 :(得分:2)

这是一个迟到的答案,但它没有使用库,因此有些人可能会觉得它很有帮助。

/**
 * Returns a non-destructive Array of elements that are not found in
 * any of the parameter arrays.
 *
 * @param {...Array} var_args   Arrays to compare.
 */
Array.prototype.uniqueFrom = function() {
  if (!arguments.length)
    return [];
  var a1 = this.slice(0); // Start with a copy

  for (var n=0; n < arguments.length; n++) {
    var a2 = arguments[n];
    if (!(a2 instanceof Array))
      throw new TypeError( 'argument ['+n+'] must be Array' );

    for(var i=0; i<a2.length; i++) {
      var index = a1.indexOf(a2[i]);
      if (index > -1) {
        a1.splice(index, 1);
      } 
    }
  }
  return a1;
}

示例:

var sheetUsers = ['joe@example.com','fred@example.com','sam@example.com'];
var siteViewers = ['joe@example.com','fred@example.com','lucy@example.com'];
var viewersToAdd = sheetUsers.uniqueFrom(siteViewers);  // [sam@example.com]
var viewersToRemove = siteViewers.uniqueFrom(sheetUsers);  // [lucy@example.com]

答案 7 :(得分:1)

 findDiff = (A, B) => {
     return  A.filter(function (a) {
          return !B.includes(a);
     });
 }