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

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

并获得

[2, 3]

当前回答

与效率无关,但很容易理解,这里有一个集合的并和交的例子,它处理集合的数组和集合的集合。

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);

其他回答

使用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。

使用jQuery:

var a = [1,2,3];
var b = [2,3,4,5];
var c = $(b).not($(b).not(a));
alert(c);

解决它 从索引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:该算法仅适用于数字和普通字符串,任意对象数组的交集可能无法工作。

我会用对我来说最有效的方法来贡献:

if (!Array.prototype.intersect){
Array.prototype.intersect = function (arr1) {

    var r = [], o = {}, l = this.length, i, v;
    for (i = 0; i < l; i++) {
        o[this[i]] = true;
    }
    l = arr1.length;
    for (i = 0; i < l; i++) {
        v = arr1[i];
        if (v in o) {
            r.push(v);
        }
    }
    return r;
};
}

我扩展了tarulen的答案,以适用于任何数量的数组。它也应该适用于非整数值。

function intersect() { 
    const last = arguments.length - 1;
    var seen={};
    var result=[];
    for (var i = 0; i < last; i++)   {
        for (var j = 0; j < arguments[i].length; j++)  {
            if (seen[arguments[i][j]])  {
                seen[arguments[i][j]] += 1;
            }
            else if (!i)    {
                seen[arguments[i][j]] = 1;
            }
        }
    }
    for (var i = 0; i < arguments[last].length; i++) {
        if ( seen[arguments[last][i]] === last)
            result.push(arguments[last][i]);
        }
    return result;
}