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. 两个数组的交集