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

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

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

得到

[2, 3]

【问题讨论】:

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

标签: javascript data-structures intersection


【解决方案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() 还会为您提供其他非数字成员,您永远不需要触摸。
            猜你喜欢
            • 2022-12-14
            • 1970-01-01
            • 1970-01-01
            • 2018-03-27
            • 2010-12-08
            • 2010-12-17
            • 1970-01-01
            • 1970-01-01
            • 2017-11-04
            相关资源
            最近更新 更多