這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助
前言
您或許會疑惑,網上那么多去重方法,這篇文章還有什么意義?
別著急,這篇文章只節選了簡單的,好玩的,古老的,有實際講解意義的去重方法,除了去重的實作以外,我還將和您分享這其中的其他細節和拓展,
您或許不理解,為什么只有五種?
當然,我可以舉例出更多的例子來,但那有什么意義呢?作業中用不到那么多,會其中一二就可以,即使是面試,能說出五種也是完全足夠的,所以,我們完全沒有必要去記憶更多的去重方式,
五種方式
最簡單的方法,ES6的Set去重(最推薦)
這個方法是我日常開發中最喜歡用的方法,因為,他的使用方法是所有去重中最簡單的,而我是一個懶癌患者,
new Set是ES6新推出的一種型別,他和陣列的區別在于,Set型別中的資料不可以有重復的值,當然,陣列的一些方法Set也無法呼叫,
使用方法:其實很簡單,將一個陣列轉化為Set資料,再轉化回來,就完成了去重,
const arr = [1,1,2,2,3,3,4,4,5,5];
const setData = https://www.cnblogs.com/smileZAZ/archive/2023/02/13/Array.from(new Set(arr));
console.log(setData);
圖例↓

但是Set去重有一個弊端,他無法去重參考型別的資料,比如物件陣列,
圖例:

所以如果您的陣列中都是值型別的資料(比如全string或者全number),那么使用Set進行去重一定是首選,會為您減少很多的麻煩,
最古老的方法,雙重for回圈去重
在很早以前,還沒有Set,沒有map,filter的時候,雙重for回圈幾乎是去重的唯一方式,
//雙重回圈去重
const handleRemoveRepeat = (arr) => {
for (let i=0,len = arr.length; i < len; i++) {
for (let j = i + 1; j < len; j++) {
if (arr[i] === arr[j]) {
arr.splice(j, 1);
j--;
len--;
}
}
}
return arr;
};
圖例:

這里有一個有意思的地方,或許您不太明白,為什么我的for回圈的初始運算式中宣告了兩個東西:let i = 0;len = arr.length;
我來給您解答:

被圈起來的三個表示的是for回圈的三個運算式,依次分別是:初始運算式,判斷運算式,自增運算式,其中,初始運算式在for回圈開始的時候會執行一次,以后就不會再執行了,但是判斷運算式和自增運算式會在每一次回圈的時候都去執行,
如果您不太理解文字表達,沒關系,我畫了張圖,


您或許已經發現,后一個圈中的內容會陷入一個回圈,
但這和我們一開始len = arr.length有什么關系呢?
值得注意的是,如果一開始定義,那么每一次回圈,都需要走 arr.length,length可是個方法,雖然他的消耗并不大,但在for回圈中這個消耗會被方法,假設這個回圈需要回圈10000次呢,length就會被執行10000次,
最雞肋的去重方式,indexOf去重
indexOf還是相對簡單又雞肋,為什么說他雞肋呢?說難吧,indexOf方法確實比上文的雙重for回圈簡單,說簡單吧,嘿,他沒Set方法去重來的更簡單,所以雞肋,
//去重
const handleRemoveRepeat = (arr) => {
let repeatArr = [];
for (let i = 0,len = arr.length ; i < len; i++)
if (repeatArr.indexOf(arr[i]) === -1) repeatArr.push(arr[i])
return repeatArr;
}
圖例:

同樣的,這個方法也有一個細節點,您或許已經發現了,上文的if和for沒有花括號;是的;for和if都默認對下面一條陳述句負責,在沒有必要的情況下,不用多加一個{},
或許您會覺得這不可讀,這就是有意思的地方了,這是一個工具類方法,注定被藏在utils中的一個方法,他無關業務邏輯,并不需要有太大可讀性,
而且,這么寫還有一個很原因:給人的視覺沖擊會比較大,說點人話就是 -----很裝逼;
一種類似于indexOf的去重方法,includes去重
使用includes的去重方法和indexOf不能說很像,基本上一模一樣,變換的僅僅只是判斷方法,
includes的判斷方法更簡單了,回圈陣列的每一樣,用新陣列檢測當前陣列中是否包含陣列項,如果不包含,則追加該元素
const handleRemoveRepeat = (arr) => {
let repeatArr = [];
for (let i = 0,len = arr.length ; i < len; i++)
if (!repeatArr.includes(arr[i])) repeatArr.push(arr[i])
return repeatArr;
}
圖例

includes方法在除了去重以外的場景,還是很好用的,
最有趣的去重方法,使用filter去重,
使用filter配合indexOf進行的去重程序,真的可以非常的簡單且富含趣味性,
//去重 const handleRemoveRepeat = (arr) => arr.filter((item,index) => arr.indexOf(item,0) === index);
是的,沒了,就一行,
圖例

您是否沒有反應過來?乍一看,不知道他是怎么完成去重的,
小問題,我為您解答疑惑,
indexOf的特性是回傳被查找的目標中包含的第一個位置的索引

如圖,下標為0和下標為4的位置存盤的都是“1”,但是indexOf()只回傳了0,因為indexOf的特性是回傳被查找的目標中包含的第一個位置的索引,
同樣的,我們可以利用這個特性,來完成去重,文字描述恐怕很難表達準確,您可以看看下面的這張圖,


您或許會問:如果要去重物件陣列怎么辦?
去除物件陣列的方式他并不是很穩定,這不像我們去重值型別資料的陣列,上面的五種方法隨便復制一種,往里面一呼叫就好了,絕對不會出問題,
但是物件陣列去重,需要有一個去重條件,也就是根據哪個欄位進行去重,
用雙重回圈去重舉個例子:

圖例

如上圖,我們就是拿資料的id作為去重條件的,
像這樣的物件陣列就不能直接提供方法,因為每一個場景下的物件陣列都不一定一樣,我這是根據id去重,萬一其他地方需要根據其他欄位去重呢,
所以,如果您需要去重物件,根據上方的截圖中的代碼,使用雙重for回圈的方法,自己自定義一個可以滿足您當前業務需求的去重方法,
本文轉載于:
https://juejin.cn/post/7152759573978284040
如果對您有所幫助,歡迎您點個關注,我會定時更新技術檔案,大家一起討論學習,一起進步,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/543802.html
標籤:其他

