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

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

并获得

[2, 3]

当前回答

我扩展了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;
}

其他回答

如果只使用关联数组呢?

function intersect(a, b) {
    var d1 = {};
    var d2 = {};
    var results = [];
    for (var i = 0; i < a.length; i++) {
        d1[a[i]] = true;
    }
    for (var j = 0; j < b.length; j++) {
        d2[b[j]] = true;
    }
    for (var k in d1) {
        if (d2[k]) 
            results.push(k);
    }
    return results;
}

编辑:

// new version
function intersect(a, b) {
    var d = {};
    var results = [];
    for (var i = 0; i < b.length; i++) {
        d[b[i]] = true;
    }
    for (var j = 0; j < a.length; j++) {
        if (d[a[j]]) 
            results.push(a[j]);
    }
    return results;
}

如果你的数组是排序的,这应该运行在O(n),其中n是min(a.length, b.length)

function intersect_1d( a, b ){
    var out=[], ai=0, bi=0, acurr, bcurr, last=Number.MIN_SAFE_INTEGER;
    while( ( acurr=a[ai] )!==undefined && ( bcurr=b[bi] )!==undefined ){
        if( acurr < bcurr){
            if( last===acurr ){
                out.push( acurr );
            }
            last=acurr;
            ai++;
        }
        else if( acurr > bcurr){
            if( last===bcurr ){
                out.push( bcurr );
            }
            last=bcurr;
            bi++;
        }
        else {
            out.push( acurr );
            last=acurr;
            ai++;
            bi++;
        }
    }
    return out;
}

使用Underscore.js或lodash.js

_.intersection( [0,345,324] , [1,0,324] )  // gives [0,324]

这是一个现代和简单的ES6方式来做,也非常灵活。 它允许您指定多个数组作为与主题数组进行比较的数组,并且可以在包含和独占模式下工作。

// =======================================
// The function
// =======================================

function assoc(subjectArray, otherArrays, { mustBeInAll = true } = {}) {
  return subjectArray.filter((subjectItem) => {
    if (mustBeInAll) {
      return otherArrays.every((otherArray) =>
        otherArray.includes(subjectItem)
      );
    } else {
      return otherArrays.some((otherArray) => otherArray.includes(subjectItem));
    }
  });
}

// =======================================
// The usage
// =======================================

const cheeseList = ["stilton", "edam", "cheddar", "brie"];
const foodListCollection = [
  ["cakes", "ham", "stilton"],
  ["juice", "wine", "brie", "bread", "stilton"]
];

// Output will be: ['stilton', 'brie']
const inclusive = assoc(cheeseList, foodListCollection, { mustBeInAll: false }),

// Output will be: ['stilton']
const exclusive = assoc(cheeseList, foodListCollection, { mustBeInAll: true })

实例:https://codesandbox.io/s/zealous-butterfly-h7dgf?fontsize=14&hidenavigation=1&theme=dark

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