用javascript实现数组交叉的最简单、无库代码是什么?我想写

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

并获得

[2, 3]

当前回答

下面是一个使用可选的比较函数处理多个数组的简单实现:

函数交叉(数组,compareFn = (val1, val2) => (val1 == val2)) { 如果数组。长度< 2)返回数组[0]?[] Const array1 = arrays[0] const array2 =交集(arrays.slice(1), compareFn) array1返回。过滤器(val1 =>数组2。if (val2 => compareFn(val1, val2))) } console.log(十字路口([[1,2,3],[2、3、4、5]])) console.log(十字路口([[{id: 1}, {id: 2}], [{id: 1}, {id: 3}]], (val1, val2) => val1。Id === val2.id)

其他回答

使用一个数组创建一个Object,并循环遍历第二个数组以检查该值是否作为key存在。

function intersection(arr1, arr2) {
  var myObj = {};
  var myArr = [];
  for (var i = 0, len = arr1.length; i < len; i += 1) {
    if(myObj[arr1[i]]) {
      myObj[arr1[i]] += 1; 
    } else {
      myObj[arr1[i]] = 1;
    }
  }
  for (var j = 0, len = arr2.length; j < len; j += 1) {
    if(myObj[arr2[j]] && myArr.indexOf(arr2[j]) === -1) {
      myArr.push(arr2[j]);
    }
  }
  return myArr;
}

下面是underscore.js的实现:

_.intersection = function(array) {
  if (array == null) return [];
  var result = [];
  var argsLength = arguments.length;
  for (var i = 0, length = array.length; i < length; i++) {
    var item = array[i];
    if (_.contains(result, item)) continue;
    for (var j = 1; j < argsLength; j++) {
      if (!_.contains(arguments[j], item)) break;
    }
    if (j === argsLength) result.push(item);
  }
  return result;
};

来源:http://underscorejs.org/docs/underscore.html部分- 62

使用Array.prototype.filter和Array.prototype.includes的组合:

const filteredArray = array1.filter(value => array2.includes(value));

对于较旧的浏览器,使用Array.prototype.indexOf且不使用箭头函数:

var filteredArray = array1.filter(function(n) {
    return array2.indexOf(n) !== -1;
});

NB !.includes和. indexof都在内部使用===来比较数组中的元素,所以如果数组包含对象,它只比较对象引用(而不是对象的内容)。如果你想指定自己的比较逻辑,请使用Array.prototype.some。

通过使用.pop而不是.shift可以提高@atk实现对原语排序数组的性能。

function intersect(array1, array2) {
   var result = [];
   // Don't destroy the original arrays
   var a = array1.slice(0);
   var b = array2.slice(0);
   var aLast = a.length - 1;
   var bLast = b.length - 1;
   while (aLast >= 0 && bLast >= 0) {
      if (a[aLast] > b[bLast] ) {
         a.pop();
         aLast--;
      } else if (a[aLast] < b[bLast] ){
         b.pop();
         bLast--;
      } else /* they're equal */ {
         result.push(a.pop());
         b.pop();
         aLast--;
         bLast--;
      }
   }
   return result;
}

我使用jsPerf创建了一个基准测试。使用。pop要快三倍。

解决它 从索引0开始逐一检查,然后创建一个新数组。

像这样的东西,不过测试不太好。

function intersection(x,y){
 x.sort();y.sort();
 var i=j=0;ret=[];
 while(i<x.length && j<y.length){
  if(x[i]<y[j])i++;
  else if(y[j]<x[i])j++;
  else {
   ret.push(x[i]);
   i++,j++;
  }
 }
 return ret;
}

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

PS:该算法仅适用于数字和普通字符串,任意对象数组的交集可能无法工作。