JS常用的求交集、并集、差集的方法
普通数组
示例数组
let a = [1, 2, 3];
let b = [4, 3, 2];
一、并集(A∪B)
let union = new Set([...a, ...b]);
let union1 = Array.from(new Set(a.concat(b)))
// Set {1, 2, 3, 4}
//先b筛选a中没有的,再连接数组
let union2 = a.concat(b.filter(val => !a.includes(val)));
let union3 = a.concat(b.filter(val=> a.indexOf(val) === -1));
//考虑NaN(数组中含NaN)
let a1 = [1, 2, 3, NaN];
let b1 = [2, 4, 5, NaN];
let aHasNaN = a.some(val => isNaN(val));
let bHasNaN = b.some(val => isNaN(val));
let union4 = a.concat(b.filter(val=> a.indexOf(val) === -1 && !isNaN(val)))
.concat(!aHasNaN & bHasNaN ? [NaN] : []);
// [1, 2, 3, NaN, 4, 5]
二、交集(A∩B)
// 交集
let intersection1 = new Set([...a].filter(val => b.has(val)));
// set {2, 3} 返回两数组都有的元素
let intersection2 = a.filter(val => b.includes(val));
let intersection3 = a.filter(val=> b.indexOf(val) > -1);
// 考虑NaN(数组中含NaN)
let a = [1, 2, 3, NaN];
let b = [2, 4, 5, NaN];
let aHasNaN = a.some(v => isNaN(v));
let bHasNaN = b.some(v => isNaN(v));
let intersection4 = a.filter(v=> b.indexOf(v) > -1)
.concat(aHasNaN & bHasNaN ? [NaN] : []);
// [2, NaN]
三、差集(A-B)
// 差集(a 相对于 b 的差集) 属于a不属于b的元素
let difference1 = new Set([...a].filter(val => !b.has(val)));
// Set {1} 返回a中,b没有的元素
//返回a与b数组区别的集合(交集取反)
let a = [1, 2, 3];
let b = [2, 4, 5];
let difference = a.concat(b)
.filter(v => !a.includes(v) || !b.includes(v));
console.log(difference)// [1,3,4,5]
let aSet = new Set(a);
let bSet = new Set(b)
//
let difference = Array.from(new Set(a.concat(b).filter(v => !aSet.has(v) || !bSet.has(v))));
console.log(difference) // [1,3,4,5]
// 考虑NaN(数组中含NaN)
let a = [1, 2, 3, NaN];
let b = [2, 4, 5];
let aHasNaN = a.some(v=> isNaN(v));
let bHasNaN = b.some(v=> isNaN(v));
//
let difference = a.filter(v => b.indexOf(v) === -1 && !isNaN(v))
.concat(b.filter(v=> a.indexOf(v) === -1 && !isNaN(v))).concat(aHasNaN ^ bHasNaN ? [NaN] : []);
console.log(difference) // [1, 3, 4, 5, NaN]
//set转为数组
let c = Array.from(difference )
let d = [...difference ]
//去重
let res1 = [...new Set(a)]
let res2 = Array.from(new Set(a));
对象数组
示例数组
let a=[
{id:'01',name:'product01'},
{id:'02',name:'product02'},
{id:'03',name:'product03'},
{id:'04',name:'product04'},
{id:'05',name:'product05'}
];
let b=[
{id:'03',name:'product03'},
{id:'06',name:'product06'},
{id:'07',name:'product07'},
{id:'08',name:'product08'},
];
var obj={};
var arr=a.concat(b);
一、并集(A∪B)
// 每次遍历将还未出现的项进行收集
arr.reduce(function(pre,cur){
if(!obj.hasOwnProperty(cur.id)){
pre.push(cur);
}
obj[cur.id]=true;
return pre;
},[])
二、交集(A∩B)
let aids = a.map(item => item.id) //[01,02,03]
let union = b.filter(function(item){
return aids.indexOf(item.id)!==-1 // 返回相同的元素
})
// 交集:定义一个对象,通过其属性值是否出现多次判断交集
arr.reduce(function(pre,cur){
obj.hasOwnProperty(cur.id)?pre.push(cur):obj[cur.id]=true;
return pre;
},[]);
三、差集(A-B)
//找出a数组中,b数组没有的对象
let res = a.filter(item=> {
return b.every(item1 =>{
return item.id !== item1.id
})
})
四、补集
//补集:a中每一项都不在b中
//A是S的一个子集,由S中所有不属于A的元素组成的集合,叫做子集A在S中的绝对补集。
//购物车一组商品,选中和未选中分为两组,拆单用
let test=a.reduce(function(pre,cur){
if(b.every(item=>item.id!==cur.id)){
pre.push({name:cur.name})
}
return pre;
},[])