在JavaScript中获取三个数组的交集

4
我需要制作一个工具,检查3个数组的交集。 以下是我的JS实现:
function intersection(array1, array2, array3) {    
    let intermediateList = [];
    let intermediateList2 = [];
    for (let i = 0; i < array1.length; i++) {
        if (!(array2.indexOf(array1[i]) == -1)) {
            intermediateList.push(array1[i]);
        }        
        for (let j = 0; j < intermediateList.length; j++) {
            if (!(intermediateList.indexOf(array3[j]) == -1)) {
                intermediateList2.push(intermediateList[i]);
            }
        }
    }
    let endList = [ ...intermediateList, ...intermediateList2];
    return endList;    
}

intersection([5, 10, 15, 20], [15, 88, 1, 5, 7], [1, 10, 15, 5, 20])
//  [5, 15] /--> fine

intersection([5, 10, 15, 20, 40, 32], [32, 15, 88, 1, 5, 7, 40], [1, 10, 15, 5, 20, 40, 32])
// [5, 15, 40, 32, undefined, undefined, undefined] /--> can someone spot why do I get those undefined values?

你如何使用 reduce 来实现这个功能?

这取决于如何处理重复值。 - Slai
请将此内容转移到 代码审查 - Adam H
3
函数intersect3(a, b, c)的作用是求a、b、c三个集合的交集,实现方式为先对b和c求交集,再对结果与a求交集。 - Bergi
你可以将其扩展到任意数量的数组 const intersectN = (a, b, ...c) => !c.length ? intersect2(a, b) : intersectN(intersect2(a, b), ...c);(应该支持尾部优化)。 - Paul S.
1个回答

4

您的函数有一个嵌套的for循环,每次外部循环运行时都会迭代intermediateList。然后您使用索引i而不是索引j推送一个值,但是这只有在两个for循环没有嵌套而是链接在一起时才有效。

function intersection(array1, array2, array3) {
    let intermediateList = [];
    let intermediateList2 = [];
    for (let i = 0; i < array1.length; i++) {
        if (array2.indexOf(array1[i]) !== -1) {
            intermediateList.push(array1[i]);
        }
    }
    for (let j = 0; j < intermediateList.length; j++) {
        if (array3.indexOf(intermediateList[j]) !== -1) {
            intermediateList2.push(intermediateList[j]);
        }
    }
    return intermediateList2;
}

console.log(intersection([5, 10, 15, 20], [15, 88, 1, 5, 7], [1, 10, 15, 5, 20]));
console.log(intersection([5, 10, 15, 20, 40, 32], [32, 15, 88, 1, 5, 7, 40], [1, 10, 15, 5, 20, 40, 32]));
.as-console-wrapper { max-height: 100% !important; top: 0; }

你可以减少参数,并返回一个包含共同值的数组。

const intersection = (...array) => array.reduce((a, b) => a.filter(v => b.includes(v)));

console.log(intersection([5, 10, 15, 20], [15, 88, 1, 5, 7], [1, 10, 15, 5, 20]));
console.log(intersection([5, 10, 15, 20, 40, 32], [32, 15, 88, 1, 5, 7, 40], [1, 10, 15, 5, 20, 40, 32]));


非常好地表达。 - leonardofed

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接