JavaScript中利用set集合去重簡(jiǎn)潔高效,通過(guò)new set(arr)創(chuàng)建唯一值集合再轉(zhuǎn)回?cái)?shù)組即可。但set無(wú)法去除nan重復(fù)值,也無(wú)法識(shí)別相同對(duì)象字面量;對(duì)于此類情況需使用Filter和indexof或第三方庫(kù)如lodash處理;此外set可用于其他數(shù)據(jù)結(jié)構(gòu)的間接去重,例如將鏈表轉(zhuǎn)為數(shù)組再使用set,最后轉(zhuǎn)回原始結(jié)構(gòu);對(duì)于按對(duì)象屬性去重的復(fù)雜場(chǎng)景,可使用map結(jié)合filter方法實(shí)現(xiàn),根據(jù)指定屬性過(guò)濾重復(fù)項(xiàng)。
JavaScript中,利用Set集合進(jìn)行去重是一種非常簡(jiǎn)潔高效的方式。它能快速移除數(shù)組中的重復(fù)元素,讓你的代碼更清晰易讀。
解決方案:
Set對(duì)象天生具備去重的特性。你可以將數(shù)組轉(zhuǎn)換為Set,然后再將Set轉(zhuǎn)換回?cái)?shù)組,這樣就得到了去重后的結(jié)果。
function uniqueArray(arr) { return [...new Set(arr)]; } // 示例 const myArray = [1, 2, 2, 3, 4, 4, 5]; const uniqueArrayResult = uniqueArray(myArray); console.log(uniqueArrayResult); // 輸出: [1, 2, 3, 4, 5]
這段代碼的核心在于new Set(arr),它會(huì)創(chuàng)建一個(gè)包含arr中所有唯一值的Set對(duì)象。然后,使用擴(kuò)展運(yùn)算符…將Set對(duì)象轉(zhuǎn)換回?cái)?shù)組。
Set去重相比傳統(tǒng)循環(huán)判斷的方式,代碼量更少,可讀性更強(qiáng),性能也通常更好,尤其是在處理大型數(shù)組時(shí)。
Set集合去重有哪些局限性?
雖然Set去重很方便,但它并非萬(wàn)能。例如,Set認(rèn)為NaN和NaN是不同的,因此無(wú)法去除數(shù)組中多個(gè)NaN值。此外,Set無(wú)法區(qū)分對(duì)象,即使兩個(gè)對(duì)象字面量看起來(lái)完全相同,Set也會(huì)認(rèn)為它們是不同的。
const arrWithNaN = [1, NaN, NaN, 2]; const uniqueArrWithNaN = [...new Set(arrWithNaN)]; console.log(uniqueArrWithNaN); // 輸出: [1, NaN, NaN, 2] const arrWithObjects = [{a: 1}, {a: 1}]; const uniqueArrWithObjects = [...new Set(arrWithObjects)]; console.log(uniqueArrWithObjects); // 輸出: [{a: 1}, {a: 1}]
對(duì)于包含NaN或?qū)ο蟮臄?shù)組,可能需要使用其他去重方法,例如使用filter和indexOf,或者使用第三方庫(kù)如Lodash。
除了數(shù)組,Set還能用于其他數(shù)據(jù)結(jié)構(gòu)的去重嗎?
Set主要用于數(shù)組去重,但它也可以間接用于其他數(shù)據(jù)結(jié)構(gòu)的去重。例如,你可以先將鏈表或樹轉(zhuǎn)換為數(shù)組,然后使用Set去重,最后再將結(jié)果轉(zhuǎn)換回原始數(shù)據(jù)結(jié)構(gòu)。這種方法的效率取決于數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)換為數(shù)組的效率。
// 假設(shè)你有一個(gè)鏈表 toArray() 方法將其轉(zhuǎn)換為數(shù)組 // 示例: // class LinkedList { // constructor() { // this.head = null; // } // toArray() { // let arr = []; // let current = this.head; // while(current) { // arr.push(current.data); // current = current.next; // } // return arr; // } // } // const linkedList = new LinkedList(); // // ... 向鏈表添加數(shù)據(jù) ... // const arrayFromLinkedList = linkedList.toArray(); // const uniqueArrayFromLinkedList = [...new Set(arrayFromLinkedList)]; // // 然后你可以將 uniqueArrayFromLinkedList 轉(zhuǎn)換回鏈表
這種方法需要根據(jù)具體的數(shù)據(jù)結(jié)構(gòu)進(jìn)行調(diào)整,確保轉(zhuǎn)換過(guò)程不會(huì)丟失關(guān)鍵信息。
如何處理更復(fù)雜的去重場(chǎng)景,例如根據(jù)對(duì)象的某個(gè)屬性去重?
當(dāng)需要根據(jù)對(duì)象的某個(gè)屬性進(jìn)行去重時(shí),Set本身無(wú)法直接實(shí)現(xiàn)。你需要使用其他方法,例如使用Map或者reduce方法。
function uniqueArrayByProperty(arr, property) { const map = new Map(); return arr.filter((item) => { if (!map.has(item[property])) { map.set(item[property], true); return true; } return false; }); } // 示例 const myArray = [{id: 1, name: 'A'}, {id: 2, name: 'B'}, {id: 1, name: 'C'}]; const uniqueArrayById = uniqueArrayByProperty(myArray, 'id'); console.log(uniqueArrayById); // 輸出: [{id: 1, name: 'A'}, {id: 2, name: 'B'}]
這段代碼使用Map來(lái)存儲(chǔ)已經(jīng)出現(xiàn)過(guò)的屬性值,然后使用filter方法過(guò)濾掉重復(fù)的對(duì)象。這種方法可以靈活地根據(jù)不同的屬性進(jìn)行去重。