在 JavaScript 中,如何求出两个数组的交集和差集?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在 JavaScript 中,如何求出两个数组的交集和差集?相关的知识,希望对你有一定的参考价值。

两个任意元素的数组,比较出两个数组中相同的元素和不同的元素。

参考技术A 相同的a.filter(function(v)returnb.indexOf(v)>-1)不同的 a.filter(function(v) return !(b.indexOf(v) > -1) ).concat(b.filter(function(v) return !(a.indexOf(v) > -1))) 参考技术B // 定义数组
a = [1,2,3,4,5,6,7,8,9,10]
b = [3,2,6,7,8,100,24]
// 把a数组转化成object
var hash = ;
for(var i=0,max=a.length; i<max; i++)
var obj = ;
hash[a[i]] = true;

// 通过hash检测b数组中的元素
for(var i=0, max=b.length; i<max; i++)
if(typeof hash[b[i]] !== "undefined")
// 相同元素

else
// 不同元素

如何从 jquery 或 javascript 中的两个不同数组中查找唯一记录?

【中文标题】如何从 jquery 或 javascript 中的两个不同数组中查找唯一记录?【英文标题】:How to find unique records from two different array in jquery or javascript? 【发布时间】:2011-08-19 21:42:49 【问题描述】:

我想从两个不同的数组中获取唯一值。

JavaScript 中的两个数组如下:

<script>
var a=new Array;
var b=new Array;
a='a','b','c','d','e'
b='a','d','e','c' 
</script>

我想要这样的输出:

new array => 'a','c','d','e'

如何使用 JavaScript 原型函数或 jQuery 函数从两个数组中找到唯一记录?

【问题讨论】:

【参考方案1】:

找到原始答案:JavaScript array difference

在这种情况下,您可以使用Set。它针对这种操作(联合、交叉、差异)进行了优化。

确保它适用于您的案例,一旦它不允许重复。

var a = new JS.Set([1,2,3,4,5,6,7,8,9]);
var b = new JS.Set([2,4,6,8]);

a.intersection(b);//intersect will give you the common one

【讨论】:

谢谢,我想从两个没有差异的数组中获取唯一值。 @Abhishek - 检查设置链接是否也有可用的操作【参考方案2】:

我不知道您的条款是否正确。 Unique 值对我来说将是在任一数组中只出现一次的成员。根据您的示例,您似乎想要两个数组中都存在的成员(公共值或交集)。

您可以使用 jQuery 来处理这个问题。 grep() 是你的朋友。

你可以不用 jQuery 来做到这一点,但我不确定原生的 filter()indexOf() 方法是否有最好的浏览器支持。

var a = ['a', 'b', 'c', 'd', 'e'],
    b = ['a', 'd', 'e', 'c'];

var common = $.grep(a, function(element) 
    return $.inArray(element, b) !== -1;
);

console.log(common); // ["a", "c", "d", "e"]

_.intersection(arr1, arr2) 使用下划线很容易。

jsFiddle.

【讨论】:

@alex 感谢 Ans,但我在 Jsfiddle 示例中获得了 undefined .. 中的控制台..,我在我的应用程序中使用了 Jquery 1.3.2.min.js.. 还有其他方式吗.. @Abhishek 这只是意味着您没有控制台对象。 Try this. 您不需要 filter() 或 indexOf() 来使用纯 JavaScript。 POJS 将比 jQuery 的 grepinArray 函数高效得多。 @RobG 显然,但它在概念上不会像没有它们的 jQuery 代码那样相似。您必须编写自己的循环,这永远不会那么漂亮。 :)【参考方案3】:

我想借助 JavaScript 中的关联数组支持来执行此操作。

<script>
var a=new Array;
var b=new Array;
a='a','b','c','d','e'
b='a','d','e','c' 

var uniqueArray = new Array;
var tempArray = new Array;

var j = 0;
for(var i = 0; i < a.length; i++) 
    if(!tempArray[a[i]]) 
        tempArray[a[i]] = true;
        uniqueArray[j++] = a[i];
    


for(i = 0; i < b.length; i++) 
    if(!tempArray[b[i]]) 
        tempArray[b[i]] = true;
        uniqueArray[j++] = b[i];
    


</script>

【讨论】:

【参考方案4】:

像这样:

var a=['a','b','c','d','e']; //Use brackets
var b=['a','d','e','c']

var c = a.concat(b).sort();

var uniques = ;

for(var i=0; i<c.length; i++)
   uniques[c[i]] = true;

var uniquesArray = [];
for(var u in uniques)
  uniquesArray.push(u)

现在 uniquesArray 只包含唯一值。 希望这会有所帮助

【讨论】:

我喜欢这种用于查找“不同”值的解决方案,但对我来说,“唯一”意味着仅在任一数组中出现一次的值。但是按照 OP 中的示例预期输出,我认为这里真正想要的是“通用”值,即两个数组中都存在的值。【参考方案5】:

我认为你真的想写:

<script type="text/javascript">
var a = ['a','b','c','d','e'];
var b = ['a','d','e','c']; 
</script>

在任何情况下,您都可以对数组进行排序并从一个数组中获取不在另一个数组中的值,反之亦然,然后将两个集合连接成一个集合。您似乎被宠坏了,所以这里有一个不错的基本 javascript 版本,应该可以在大多数浏览器中使用。在旧浏览器中使用最新浏览器的新功能肯定会失败。

// Compares a to b. Returns all the elements in a that are not in b
// If c provided, add unique elements to c
function getUnique(a, b, c) 
  var c = c || [];
  var ta = a.slice().sort();
  var tb = b.slice().sort();
  var x, y, found = false;
  for (var i=0, iLen=ta.length; i<iLen; i++) 
    x = ta.shift();

    for (var j=0; j<tb.length && !found; j++)  // j.length changes each loop
      if (tb[j] == x) 
        tb.splice(j,1);  // Remove match from b
        found = true;
      
    
    if (!found) 
      c.push(x); // If no match found, store in result
    
    found = false;
  
  return c;

var a = ['a','b','d'];
var b = ['b','e'];

var d = getUnique(a, b);
alert(d);

var c = getUnique(b,a,d);
alert(d);

但是您对第一个答案的评论表明您想要两个数组共有的元素,这更简单:

function getCommon(a, b) 
  var c = [];
  var ta = a.slice().sort();
  var tb = b.slice().sort();
  var t, found;

  for (var i=0, iLen=ta.length; i<iLen; i++) 
    t = ta[i];
    found = false;

    for (var j=0, jLen=tb.length; j<jLen && !found; j++) 
      if (t == tb[j]) 
        c.push(tb.splice(j,1));
        found = true;
      
    
  
  return c;


alert(getCommon(a, b));

您需要弄清楚如何处理重复项。在第一种情况下,如果另一个数组中没有重复项,则重复项将被视为唯一。在上面,重复并不重要,除非它们在两个数组中都重复。

【讨论】:

感谢@RobG 它比 grep 函数快吗?比 jquery 函数 grep() 好在哪里 @Abhishek 在没有库的情况下做事几乎总是更快。 非常感谢@RobG,我明白了执行时间比 grep() 快,单位为毫秒。 +1 获得不错的本地答案。顺便说一句,你有什么理由不打破标签而不是使用found 作为标志(或者我错过了什么)? @Abhishek 您不应该根据毫秒的差异来选择一件事而不是另一件事。选择那些最易读的。

以上是关于在 JavaScript 中,如何求出两个数组的交集和差集?的主要内容,如果未能解决你的问题,请参考以下文章

如何在JAVA中实现两个集合的交和并

arcgis9.3中,做面编辑时,如何快速的处理两个面之间的交线,而不用一个一个节点地去点,急求!!!!

LintCode 数组

Hihocoder 1167 高等理论计算机科学 (树链的交,线段树或树状数组维护区间和)

javascript集合的交,并,补,子集的操作实现

剑指Offer(Java版)第四十题:在数组中的两个数字,如果前面一个数字大于后面的数字, 则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。 并将P对1000000007取模