javascript多種方法實現數組去重

先說說這個實例的要求:寫一個方法實現數組的去重。(要求:執行方法,傳遞一個數組,返回去重後的新數組,原數組不變,實現過程當中只能用一層循環,雙層嵌套循環也可寫,只作參考);數組

先給初學者解釋一下什麼叫數組去重(老鳥跳過):意思就是講數組裏面重復的元素去掉,好比說var arr = [3,2,4,2,1,2]; 數組去重獲得的新數組是 [3,2,4,1],就是這麼一個功能。性能

 

第一種,經過遍歷新數組來去重this

var arr = [1,'b','b',4,3,3,4,5,1]; prototype

        //第一種對象

        Array.prototype.unique1 = function(){排序

            var arr1 = []; //定義一個新數組內存

            for(var i=0;i<this.length;i++){hash

                if(arr1.indexOf(this[i]) == -1){//判斷目標數組中在原數組裏是否存在io

                    arr1.push(this[i]);console

                } 

            } 

            return arr1;

        }

        console.log(arr); //[1,'b','b',4,3,3,4,5,1]

        console.log(arr.unique1()); //[1, "b", 4, 3, 5]

        //這種方法的主要思路就是,新建一個數組,而後在原數組中,從第一個開始,看看新數組裏面有沒有這個元素,若是有,就忽略,而後進行下一個,若是沒有,則把這個元素存到新數組裏面,

        //也就是說,每一次比較,都會遍歷新數組,直到找到相同元素爲止,比較耗性能

若是你們不習慣這個寫法,能夠改爲下面的寫法,效果是同樣的:

var arr = [1,'b','b',4,3,3,4,5,1];

function unique1(arr){

            var arr1 = [];

            for(var i=0;i<arr.length;i++){

                if(arr1.indexOf(arr[i]) == -1){//判斷目標數組中在原數組裏是否存在

                    arr1.push(arr[i]);

                } 

            } 

            return arr1;

        }

        console.log(arr); //[1,'b','b',4,3,3,4,5,1]

        console.log(unique1(arr)); //[1, "b", 4, 3, 5]

下面的方法我就不改寫法了,大家能夠按照上面的格式來改寫一下,結果我也不輸出了,由於結果是同樣的,註釋寫在代碼中,慢慢體會一下

 

第二種,經過hash表(這個概念有點大,這是好東西)實現

var arr = [1,'b','b',4,3,3,4,5,1];

Array.prototype.unique2 = function(){

            var hash = {}; //定義一個hash表

            var arr1 = [];  //定義一個新數組

            for(var i=0;i<this.length;i++){

                /*

                    這裏比較難理解,咱們一步一步來看:

                    hash是一個對象,則存在鍵值對(key:value),只不過如今是爲空的,因此hash[key] = value;

                    第一步:i=0;this[i]=this[0]=1; hash[this[0]] = hash[1] , 由於hash初始爲空,沒有找到key=1的值,因此而後undefined,

                    執行下一步:hash[1] = true(此時hash對象就有了第一組鍵值對),將原數組的第一個數添加到新數組中,重複第一步

                    由於不重複的判斷hash的值都是undefined,而重複的都爲true了,因此不重複都被添加到新數組中

                    由於hash表存的值是存的地址,放在堆內存中,因此有多少個不重複的元素,就要分多少個內存來存放,因此這種方法比較佔內存,可是相比之下,這種的運算運動是最快的,

                    這也就是用空間來換取時間了,數據量比較小,推薦用此方法

                */

                if(! hash[this[i]]){

                    hash[this[i]] = true;

                    arr1.push(this[i]);

                }

            }

            return arr1;  

        }

        console.log(arr);

        console.log(arr.unique2());

 

第三種,經過遍歷自身的位置是否一致來實現

var arr = [1,'b','b',4,3,3,4,5,1];

Array.prototype.unique3 = function(){

            var arr1 = [];  //定義一個新數組

            for(var i=0;i<this.length;i++){

                if(this.indexOf(this[i])==i){

                //這裏也是indexOf遍歷,看從第一個元素在原數組中的位置,若是第一次出現的位置和下標相等,說明當前元素的不重複的,若是不等,說明該元素前面已經出現過

                    arr1.push(this[i]);

                }

            }

            return arr1;  

        }

        console.log(arr);

        console.log(arr.unique3());

 

第四種,這個有點意思,只能運用到特殊場合,就是先跟數組排序,而後22比較,輸出一個排序過的新數組

Array.prototype.unique4 = function(){

            /*

                這裏是思路是,先排序(默認從小到大),而後將原數組的第一個給新數組,

                由於是通過排序的,因此重複的只會存在在相鄰位置

                這裏就至關因而作22比較,若是相等,則進行下一組,若是不相等,則把這個數存到新數組中,用這個數再進行比較

            */

            this.sort();

            var arr1 = [this[0]];

            for(var i=1;i<this.length;i++){

                if(this[i] !== arr1[arr1.length-1]){

                    arr1.push(this[i]);

                } 

            }

            return arr1;  

        }

        console.log(arr);

        console.log(arr.unique4());

 

要求裏面還說,可使用雙層嵌套循環來實現,沒法就是用2層for循環,讓每個與原數組去比較

Array.prototype.unique5 = function(){

            //雙層循環,一一比較

            for(var i=0;i<this.length;i++){ //從0開始

                for(j= i+1;j<this.length;j++){ //從1開始,逐個比較

                    if(this[i] === this[j]){ //若是恆定

                        this.splice(j,1);   //就將這個元素刪掉

                    } 

                } 

            }

            return this;  

        }

        console.log(arr);

        console.log(arr.unique5());

 

這種寫法的循環次數太多,不推薦,有人會說,第一種和第三種不也是每次都遍歷一遍嗎?跟第5種感受也差很少呢?是的,你能這麼理解,說明你理解了,可是呢,又不是特別的理解,咱們說差很少那可就差太多了,indexOf()表示的是找到第一個匹配的元素就會中止遍歷,而第5種則是無論找不找獲得,都會把整個數組遍歷一遍,若是數據量大,那你以爲哪一個性能要好一點?

特別注意的一點:若是在比較兩兩之間的值是全等或不等的時候,必定要用恆定(===)和不恆定(!==),由於這會涉及到元素的類型上,如 1與'1'是不恆等的!

相關文章
相關標籤/搜索