用javascript实现数组交叉的最简单、无库代码是什么?我想写
intersection([1,2,3], [2,3,4,5])
并获得
[2, 3]
用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)
其他回答
这是一个现代和简单的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.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;
}
最简单、最快的O(n)和最短的方式:
函数交点(a, b) { const setA = new Set(a); 返回b.filter(value => setA.has(value)); } console.log(十字路口([1,2,3],[2、3、4、5)))
@nbarbosa几乎有相同的答案,但他将两个数组强制转换为Set,然后再转换回数组。不需要任何额外的选角。
我认为在内部使用一个对象可以帮助计算,也可以提高性能。
//方法维护每个元素的计数,也适用于负元素
function intersect(a,b){
const A = {};
a.forEach((v)=>{A[v] ? ++A[v] : A[v] = 1});
const B = {};
b.forEach((v)=>{B[v] ? ++B[v] : B[v] = 1});
const C = {};
Object.entries(A).map((x)=>C[x[0]] = Math.min(x[1],B[x[0]]))
return Object.entries(C).map((x)=>Array(x[1]).fill(Number(x[0]))).flat();
}
const x = [1,1,-1,-1,0,0,2,2];
const y = [2,0,1,1,1,1,0,-1,-1,-1];
const result = intersect(x,y);
console.log(result); // (7) [0, 0, 1, 1, 2, -1, -1]
下面是一个使用可选的比较函数处理多个数组的简单实现:
函数交叉(数组,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)