JS实现取任意类型的数组交集并集方法的思考

说到交并集避免不了判断类型是否相同,可能很多人都会想到ES6的Set类型,理所当然的认为可以用Set类型来达到取唯一。但其实没那么简单。


下面参考网上的一些代码

let a = new Set([1, 2, 3]);
let b = new Set([3, 5, 2]); 

// 并集
let unionSet = new Set([...a, ...b]);
//[1,2,3,5]

// 交集
let intersectionSet = new Set([...a].filter(x => b.has(x)));
// [2,3]

// ab差集
let differenceABSet = new Set([...a].filter(x => !b.has(x)));
// [1]

再把Set转换为数组即可.


let arr = Array.from(set);
// 或 let arr = [...set];

看起来没有什么问题,但是没有考虑到数组的值类型为Object时,Sethas()方法是无法判断的,会永远返回false在这里插入图片描述
这里使用索引的方式传入Set也无法正确判断在这里插入图片描述
唯一的办法是使用has()时也传入对应的索引
在这里插入图片描述

我们知道在JS中,复杂对象类型(Array、Object、Function、Set、Map等)在引用时都是使用数据保存在内存栈中的指针索引,而原始数据保存在内存堆中,所以在比较时都是
直接比较索引,这就导致无法直接用索引去与原始数据比较。

所以我们可以使用JSON.parse()配合JSON.stringify()来将索引转为原始数据来进行比较,以下是经过改进的代码。

 //交集
 const intersection = (a, b) => {
    let aa = new Set([...a].map(i => JSON.stringify(i)));
    let bb = new Set([...b].map(i => JSON.stringify(i)));
    return Array.from(
      new Set([...aa].filter(x => bb.has(x)).map(i => JSON.parse(i)))
    );
 };
 //并集
const union = (a, b) =>
    Array.from(
      new Set([
        ...[...a].map(i => JSON.stringify(i)),
        ...[...b].map(i => JSON.stringify(i))
      ])
    ).map(i => JSON.parse(i));
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章