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));
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章