javascript中数组交集的最简单代码

Posted

技术标签:

【中文标题】javascript中数组交集的最简单代码【英文标题】:Simplest code for array intersection in javascript 【发布时间】:2010-12-25 12:39:09 【问题描述】:

javascript 中实现数组交集的最简单、无库的代码是什么?我要写

intersection([1,2,3], [2,3,4,5])

得到

[2, 3]

【问题讨论】:

你想要简单还是快速? 优先级很简单,但不能太脑残以至于它会成为性能猪 :) break 添加到Simple js loops 将操作/秒增加到~10M 不错!但是如果它们不是数字类型呢?如果它们是需要自定义检查的自定义对象怎么办? 测试中的函数返回错误的结果。事实上,只有一种实现返回了预期的结果。 【参考方案1】:

我正在使用地图,甚至可以使用对象。

//find intersection of 2 arrs
const intersections = (arr1,arr2) => 
  let arrf = arr1.concat(arr2)
  let map = new Map();
  let union = [];
  for(let i=0; i<arrf.length; i++)
    if(map.get(arrf[i]))
      map.set(arrf[i],false);
    else
      map.set(arrf[i],true);
    
  
 map.forEach((v,k)=>if(!v)union.push(k);)
 return union;

【讨论】:

A code-only answer is not high quality。虽然此代码可能很有用,但您可以通过说明其工作原理、工作方式、何时应该使用以及它的局限性来改进它。请edit您的回答包括解释和相关文档的链接。【参考方案2】:

这是我正在使用的一个非常幼稚的实现。它是非破坏性的,并且确保不复制整体。

Array.prototype.contains = function(elem) 
    return(this.indexOf(elem) > -1);
;

Array.prototype.intersect = function( array ) 
    // this is naive--could use some optimization
    var result = [];
    for ( var i = 0; i < this.length; i++ ) 
        if ( array.contains(this[i]) && !result.contains(this[i]) )
            result.push( this[i] );
    
    return result;

【讨论】:

【参考方案3】:

coffeescript 中 N 个数组的交集

getIntersection: (arrays) ->
    if not arrays.length
        return []
    a1 = arrays[0]
    for a2 in arrays.slice(1)
        a = (val for val in a1 when val in a2)
        a1 = a
    return a1.unique()

【讨论】:

【参考方案4】:

基于 Anon 的出色回答,这个返回两个或多个数组的交集。

function arrayIntersect(arrayOfArrays)
        
    var arrayCopy = arrayOfArrays.slice(),
        baseArray = arrayCopy.pop();

    return baseArray.filter(function(item) 
        return arrayCopy.every(function(itemList) 
            return itemList.indexOf(item) !== -1;
        );
    );

【讨论】:

【参考方案5】:

希望这对所有版本都有帮助。

function diffArray(arr1, arr2) 
  var newArr = [];

  var large = arr1.length>=arr2.length?arr1:arr2;
  var small = JSON.stringify(large) == JSON.stringify(arr1)?arr2:arr1;
  for(var i=0;i<large.length;i++)
    var copyExists = false; 
    for(var j =0;j<small.length;j++)
      if(large[i]==small[j])
        copyExists= true;
        break;
      
    
    if(!copyExists)
      
        newArr.push(large[i]);
      
  

  for(var i=0;i<small.length;i++)
    var copyExists = false; 
    for(var j =0;j<large.length;j++)
      if(large[j]==small[i])
        copyExists= true;
        break;
      
    
    if(!copyExists)
      
        newArr.push(small[i]);
      
  


  return newArr;

【讨论】:

【参考方案6】:

不是关于效率,而是容易理解,这里是集合的并集和交集的例子,它处理集合的数组和集合的集合。

http://jsfiddle.net/zhulien/NF68T/

// process array [element, element...], if allow abort ignore the result
function processArray(arr_a, cb_a, blnAllowAbort_a)

    var arrResult = [];
    var blnAborted = false;
    var intI = 0;

    while ((intI < arr_a.length) && (blnAborted === false))
    
        if (blnAllowAbort_a)
        
            blnAborted = cb_a(arr_a[intI]);
        
        else
        
            arrResult[intI] = cb_a(arr_a[intI]);
        
        intI++;
    

    return arrResult;


// process array of operations [operation,arguments...]
function processOperations(arrOperations_a)

    var arrResult = [];
    var fnOperationE;

    for(var intI = 0, intR = 0; intI < arrOperations_a.length; intI+=2, intR++) 
    
        var fnOperation = arrOperations_a[intI+0];
        var fnArgs = arrOperations_a[intI+1];
        if (fnArgs === undefined)
        
            arrResult[intR] = fnOperation();
        
        else
        
            arrResult[intR] = fnOperation(fnArgs);
        
    

    return arrResult;


// return whether an element exists in an array
function find(arr_a, varElement_a)

    var blnResult = false;

    processArray(arr_a, function(varToMatch_a)
    
        var blnAbort = false;

        if (varToMatch_a === varElement_a)
        
            blnResult = true;
            blnAbort = true;
        

        return blnAbort;
    , true);

    return blnResult;


// return the union of all sets
function union(arr_a)

    var arrResult = [];
    var intI = 0;

    processArray(arr_a, function(arrSet_a)
    
        processArray(arrSet_a, function(varElement_a)
        
            // if the element doesn't exist in our result
            if (find(arrResult, varElement_a) === false)
            
                // add it
                arrResult[intI] = varElement_a;
                intI++;
            
        );
    );

    return arrResult;


// return the intersection of all sets
function intersection(arr_a)

    var arrResult = [];
    var intI = 0;

    // for each set
    processArray(arr_a, function(arrSet_a)
    
        // every number is a candidate
        processArray(arrSet_a, function(varCandidate_a)
        
            var blnCandidate = true;

            // for each set
            processArray(arr_a, function(arrSet_a)
            
                // check that the candidate exists
                var blnFoundPart = find(arrSet_a, varCandidate_a);

                // if the candidate does not exist
                if (blnFoundPart === false)
                
                    // no longer a candidate
                    blnCandidate = false;
                
            );

            if (blnCandidate)
            
                // if the candidate doesn't exist in our result
                if (find(arrResult, varCandidate_a) === false)
                
                    // add it
                    arrResult[intI] = varCandidate_a;
                    intI++;
                
            
        );
    );

    return arrResult;


var strOutput = ''

var arrSet1 = [1,2,3];
var arrSet2 = [2,5,6];
var arrSet3 = [7,8,9,2];

// return the union of the sets
strOutput = union([arrSet1, arrSet2, arrSet3]);
alert(strOutput);

// return the intersection of 3 sets
strOutput = intersection([arrSet1, arrSet2, arrSet3]);
alert(strOutput);

// of 3 sets of sets, which set is the intersecting set
strOutput = processOperations([intersection,[[arrSet1, arrSet2], [arrSet2], [arrSet2, arrSet3]]]);
alert(strOutput);

【讨论】:

【参考方案7】:

IE 中的 Array 不支持“filter”和“indexOf”。这个怎么样:

var array1 = [1, 2, 3];
var array2 = [2, 3, 4, 5];

var intersection = [];
for (i in array1) 
    for (j in array2) 
        if (array1[i] == array2[j]) intersection.push(array1[i]);
    

【讨论】:

永远不要在数组上使用for .. in。曾经。天哪。 好吧,他说“没有库”,所以它应该不受可迭代数组原型扩展的影响。但是,这是很好的一般建议。 在数组中你应该遍历它的索引。 for() 还会为您提供其他非数字成员,您永远不需要触摸。

以上是关于javascript中数组交集的最简单代码的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode Java刷题笔记—349. 两个数组的交集

LeetCode Java刷题笔记—349. 两个数组的交集

JavaScript笔试题(js高级代码片段)

在 JavaScript 中从 1..20 创建整数数组的最简单方法

Java 求解两个数组的交集

LeetCode:350. 两个数组的交集 II(python,JavaScript)