2019.08.02補:
對象數(shù)組建議直接循環(huán)然后使用工具庫(lodash)的深比較,評論里也有指出,文章的方法有些取巧了 生產(chǎn)環(huán)境不要這么玩~。
-
方法一:利用ES6的Array.from()/擴展運算符 以及 Set
Array.from(): The Array.from() method creates a new Array instance from an array-like or iterable object.
該方法接收兩個參數(shù)要轉(zhuǎn)換的非數(shù)組對象,對每個元素進行處理的方法(可選).在js中,有很多類數(shù)組對象(array-like object)和可遍歷(iterable)對象(包括ES6新增的數(shù)據(jù)結(jié)構(gòu)Set和Map),常見的類數(shù)組對象包括document.querySelectorAll()取到的NodeList,以及函數(shù)內(nèi)部的arguments對象。它們都可以通過Array.from()轉(zhuǎn)換為真正的數(shù)組,從而使用數(shù)組的方法。事實上只要對象具有l(wèi)ength屬性,就可以通過Array.from()轉(zhuǎn)換為真正的數(shù)組。
Set:A collection of unique values that may be of any type.
Set:一個可以是任何類型的獨一無二的值的集合.
function unique(arr){ return Array.from(new Set(arr)); }
你也可以這樣寫:
function unique(arr){ return [...new Set(arr)]; }
-
方法二:遍歷數(shù)組,建立新數(shù)組,利用indexOf判斷是否存在于新數(shù)組中,不存在則push到新數(shù)組,最后返回新數(shù)組
Determines the index of the specific IThing in the list.
indexOf() :方法可返回某個指定的字符串值在字符串中首次出現(xiàn)的位置。如果沒有則返回-1
function unique(arr){ var newArr = []; for(var i in arr) { if(newArr.indexOf(arr[i]) == -1) { newArr.push(arr[i]) } } return newArr; }
-
方法三:遍歷數(shù)組,利用object對象的key值保存數(shù)組值(key不重復(fù)),判斷數(shù)組值是否已經(jīng)保存在object中,未保存則push到新數(shù)組并用object[arrayItem]=true的方式記錄保存.
function unique(arr) { let hashTable = {}; let newArr = []; for(let i=0,l=arr.length;i<l;i++) { if(!hashTable[arr[i]]) { hashTable[arr[i]] = true; newArr.push(arr[i]); } } return newArr; }
-
方法四:先排序,新數(shù)組最后一項為舊數(shù)組第一項,每次插入判斷新數(shù)組最后一項是否與插入項相等
function unique(arr) { var newArr = []; var end; //end其實就是一道卡 arr.sort(); end = arr[0]; newArr.push(arr[0]); for (var i = 1; i < arr.length; i++) { if (arr[i] != end) { newArr.push(arr[i]); end = arr[i]; //更新end } } return newArr; }
以上四種方法都是對于基本數(shù)據(jù)類型而言,如果換做對象數(shù)組就無能為力了,下面是對象數(shù)組的去重方法
-
方法一:利用對象的鍵名不能重復(fù)的特點
function unique(arr){ let unique = {}; arr.forEach(function(item){ unique[JSON.stringify(item)]=item;//鍵名不會重復(fù) }) arr = Object.keys(unique).map(function(u){ //Object.keys()返回對象的所有鍵值組成的數(shù)組,map方法是一個遍歷方法,返回遍歷結(jié)果組成的數(shù)組.將unique對象的鍵名還原成對象數(shù)組 return JSON.parse(u); }) return arr; } map方法使用示例: var map = Array.prototype.map var a = map.call("Hello World", function(x) { return x.charCodeAt(0); }) // a的值為[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
存在的問題:
{x:1,y:2}與{y:2,x:1}通過JSON.stringify字符串化值不同,但顯然他們是重復(fù)的對象.
-
方法二:還是利用對象的鍵名無法重復(fù)的特點,必須知道至少一個對象數(shù)組中的對象的屬性名
var songs = [ {name:"羽根",artist:"air"}, {name:"羽根",artist:"air"}, {name:"晴天",artist:"周杰倫"}, {name:"晴天",artist:"周杰倫"}, {artist:"周杰倫",name:"晴天"} ]; function unique(songs){ let result = {}; let finalResult=[]; for(let i=0;i<songs.length;i++){ result[songs[i].name]=songs[i]; //因為songs[i].name不能重復(fù),達到去重效果,且這里必須知曉"name"或是其他鍵名 } //console.log(result);{"羽根":{name:"羽根",artist:"air"},"晴天":{name:"晴天",artist:"周杰倫"}} //現(xiàn)在result內(nèi)部都是不重復(fù)的對象了,只需要將其鍵值取出來轉(zhuǎn)為數(shù)組即可 for(item in result){ finalResult.push(result[item]); } //console.log(finalResult);[{name:"羽根",artist:"air"},{name:"晴天",artist:"周杰倫"}] return finalResult; } console.log(unique(songs));