JS數組去重


1. 基本數據類型去重
2. 對象數組的去重
3. 插件類庫的方法


基本數據類型去重


方法一:利用ES6的

  • (1)Array.from()/擴展運算符
var arr = [1,3,1,4,1,5,6,3,1,2];
function unique(arr){
    return Array.from(new Set(arr));
}
  • (2)set
var arr = [1,3,1,4,1,5,6,3,1,2];
function unique(arr){
    return [...new Set(arr)];
}
  • (3)map
function unique (arr) { 
    const seen = new Map() 
    return arr.filter((a) => !seen.has(a) && seen.set(a, 1)) 
}

方法二:兩次遍歷

思路:每遍歷一次就和之前的所有做比較,不相等則放入新的數組中;

原型方法
Array.prototype.unique = function(){
    var newArr = [],
    flag = 1;
    for(var i = 0; i < this.length; i++, flag = 1){
        for(var j = 0; j < i; j++){
            if(this[i] == this[j]){
                flag = 0; //找到相同的數字後,不執行添加數據
            }
        }
        flag ? newArr.push(this[i]) : '';
    }
    return newArr;
}

方法三:indexOf

思路:遍歷數組,建立新數組,利用indexOf判斷是否存在於新數組中,不存在則push到新數組,最後返回新數組
indexOf() :方法可返回某個指定的字符串值在字符串中首次出現的位置。如果沒有則返回-1

函數封裝                                                原型方法
function unique(arr){                                   Array.prototype.unique = function(){
    var newArr = [];                                        var newArr =[];   //一個新的臨時數組
    for(var i in arr) {                                     for (var i = 0; i < this.length; i++) {
        if(newArr.indexOf(arr[i]) == -1) {                      if ( newArr.indexof(this[i]) == -1) {
            newArr.push(arr[i])                                     newArr.push(this[i]);
        }                                                       };
    }                                                       }
    return newArr;                                          return newArr;
}                                                       }
var arr = [1,2,3,3,4];

console.log(arr.unique(arr));

方法四:對象key值

思路:遍歷數組,利用object對象的key值保存數組值(key不重複),判斷數組值是否已經保存在object中,未保存則push到新數組並用object[arrayItem]=true的方式記錄保存.
1. 創建一個新的數組存放結果,和一個空對象
2. for循環時,每次取出一個元素與對象進行對比,如果這個元素不重複,則把它存放到結果數組中,同時把這個元素的內容作爲對象的一個屬性,並賦值爲1,存入到第2步建立的對象中。
說明:對比的方法,就是每次從原數組中取出一個元素,然後到對象中去訪問這個屬性,如果能訪問到值,則說明重複。

封裝函數                                                    原型方法
function unique(arr) {                                 Array.prototype.unique = function(){
  let newArr = [];                                          var newArr = [];
  let json = {};                                            var json = {};
  for(let i=0,l=arr.length;i<l;i++) {                       for(var i = 0; i < this.length; i++){   
    if(!json[arr[i]]) {                                        if (!json[JSON.stringify(this[i])]){
      json[arr[i]] = true;                                         newArr.push(this[[i]]);
      newArr.push(arr[i]);                                         json[JSON.stringify(this[i])] = 1;
    }                                                         }
  }                                                        }
  return newArr;                                           return newArr;
}                                                       }
                                                        var s1=[{"a":10,b:20},{"a":10,b:20},{"a":60,c:30},{"f":60,d:30}];
                                                        var arr = [112,112,34,'hello',112,112,34,'hello','str','str1'];
                                                        alert(arr.unique());

評價: 推薦方法


方法五:先排序,再比較

思路:先排序,新數組最後一項爲舊數組第一項,每次插入判斷新數組最後一項是否與插入項相等
如果不相同,則將該元素存入結果數組中;

封裝函數                                                         原型方法
function unique(arr) {                                          Array.prototype.unique = function(){
    var newArr = [];
    var last;
    arr.sort();                                                     this.sort();
    lat = arr[0];                                                   var newArr = [this.[0]];
    newArr.push(arr[0]);
    for (var i = 1; i < arr.length; i++) {                          for( var i = 1; i < this.length; i++){
        if (arr[i] != last) {                                            if(this[i] !== newArr[newArr.length-1]){
            newArr.push(arr[i]);                                            newArr.push(this[i]);
            last = arr[i];  
        }                                                               }
    }                                                               }
    return newArr;                                                  return newArr;
}                                                               }

var arr = [1,2,3,3,4];
console.log(arr.unique());

評價:
比兩次遍歷效率高
問題:(侷限性)因爲在去重前進行了排序,所以最後返回的去重結果也是排序後的。如果要求不改變數組的順序去重,那這種方法便不可取了。


對象數組的去重


方法一:利用對象的鍵名不能重複的特點

 function unique(arr){
   let unique = {};
   arr.forEach(function(item){
     unique[JSON.stringify(item)]=item;//鍵名不會重複
   })
   arr = Object.keys(unique).map(function(u){ 
   //Object.keys()返回對象的所有鍵值組成的數組,map方法是一個遍歷方法,返回遍歷結果組成的數組.將unique對象的鍵名還原成對象數組
     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字符串化值不同,但顯然他們是重複的對象.

方法二:還是利用對象的鍵名無法重複的特點,必須知道至少一個對象數組中的對象的屬性名

var frames = [
         {name:"vue",artist:"mvvm"},
         {name:"vue",artist:"mvvm"},
         {name:"react",artist:"vdom"},
         {name:"react",artist:"vdom"},
        {artist:"angular",name:"data"}
    ];

function unique(songs){
    let result = {};
    let finalResult=[];
    for(let i=0;i<frames.length;i++){
        result[frames[i].name]=frames[i];   
    }
    for(item in result){
        finalResult.push(result[item]);
    }
    return finalResult;
}
console.log(unique(frames));

插件類庫的方法

  • jQuery: $.unique

  • underscore: _.unique

  • lodash

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章