javascript數(shù)組去掉重復(fù)
更新時間:2011年05月12日 23:27:46 作者:
去tx面試過幾次,基本都會考到數(shù)組去重。其實平時工作中幾乎不會用到,再者也沒認(rèn)真去了解過,所以基本上每次面到這里都會露出很大的馬腳,面試自然也over了
總得來說面試的過程還是收獲了不少,主要是認(rèn)清自己的差距到底有多大,知識面到底有多窄,適當(dāng)打擊一下自信心還是有必要的。在這里做一次全面的總結(jié),關(guān)于javascript的數(shù)組去重問題。
考慮一個問題由簡到繁相對容易接受一點,首先假設(shè)要去重的數(shù)組是比較簡單的,例如:
var arr=[1,2,2,3,'5',6,5,'',' ']
這個數(shù)組只包含了數(shù)字,字符串兩種類型。我們給數(shù)組原型上面添加去重的方法distinct,用第一種很容易想到的方法來實現(xiàn),當(dāng)然也是很笨很直接的,把這個數(shù)組復(fù)制一份然后循環(huán)兩個數(shù)組,對比當(dāng)前值與后面所有的值是否相等,如果與后面所有值都不等則把該值存到新數(shù)組里,如此最后再返回該新數(shù)組。方法如下:
//第一種方法
Array.prototype.distinct=function(){
var clone,newArr=[],n=0;
if(this.length<2)return;
clone=this;
for(var i=0,len=this.length;i<len;i++){
for(var j=i+1,len2=clone.length;j<len2;j++){
if(this[i]!==clone[j]){
n++;
}
}
if(n==(len-i-1)){
newArr.push(this[i])
}
n=0;
}
return newArr;
}
console.log([1,2,2,3,'5',6,5,'',' '].distinct());
/*獲得被check的radio的值*/
function GetRadioValue(RadioName){
var obj;
obj=document.getElementsByName(RadioName);
if(obj!=null){
var i;
for(i=0;i<obj.length;i++){
if(obj[i].checked){
return obj[i].value;
}
}
}
return null;
}
/*設(shè)置被選中屬性*/
function SetRadioCheck(RadioName,i){
var obj;
obj=document.getElementsByName(RadioName);
obj[i].setAttribute("checked","checked");
}
基本可以滿足我們的需求,對這樣簡單的類型比較確實不用費(fèi)太多的腦經(jīng),但如果數(shù)組很長呢?如此遍歷數(shù)組,數(shù)組長度為n,那么時間復(fù)雜度為n*n。顯然該方法性能還有待提升。接下來是第二種方法,用到數(shù)組排序,在排序的過程去除重復(fù)的值。
//第二種方法
Array.prototype.distinct=function(){
var newArr=this.concat().sort(),self=this;
newArr.sort(function(a,b){
var n;
if(a===b){
n=self.indexOf(a);
self.splice(n,1);
}
});
return self;
}
console.log([1,2,2,3,'5',6,5,6,6,15,5,'5',5,'',' '].distinct());
這樣代碼看起來似乎短了很多,甚至連一個for循環(huán)都沒有,但是sort得效率也高不到哪里去。再來看看第三種實現(xiàn)方法,用到的對象屬性不會重名的原理
//第三種方法
Array.prototype.distinct=function(){
var newArr=[],obj={};
for(var i=0,len=this.length;i<len;i++){
if(!obj[this[i]]){
newArr.push(this[i]);
obj[this[i]]='new';
}
}
return newArr;
}
console.log([1,2,2,3,'5',6,5,6,6,15,5,'5',5,'',' '].distinct());
第三種方法運(yùn)行看下結(jié)果,會發(fā)現(xiàn)跟上面的方法實現(xiàn)的結(jié)果不一致,細(xì)看原來它把數(shù)字5和字符串5當(dāng)成重復(fù)的值給去掉了??磥眍愋捅仨毐4嫫饋砣缓笤倥袛嗍欠裣嗟?,這樣便有了下面的第三種方法的補(bǔ)充版
//第三種方法補(bǔ)充版
Array.prototype.distinct=function(){
var newArr=[],obj={};
for(var i=0,len=this.length;i<len;i++){
if(!obj[typeof(this[i])+this[i]]){
newArr.push(this[i]);
obj[typeof(this[i])+this[i]]='new';
}
}
return newArr;
}
上面舉的例子是很簡單的類型,我們拿更復(fù)雜的類型來測試一下
console.log([1,null,2,{a:'vc'},{},'5',6,5,6,{a:'vv'},15,5,'5',5,'',' ',[1],[1],[1,2],,].distinct());
發(fā)現(xiàn){a:'vc'},{},{a:'vv'}這些不同的對象還是會被剔除掉,如果數(shù)組里面有對象則要繼續(xù)遍歷對象里面的屬性和值,繼續(xù)第三種方法的加強(qiáng)
//第三種方法加強(qiáng)版
Array.prototype.distinct=function(){
var sameObj=function(a,b){
var tag = true;
if(!a||!b)return false;
for(var x in a){
if(!b[x])
return false;
if(typeof(a[x])==='object'){
tag=sameObj(a[x],b[x]);
}else{
if(a[x]!==b[x])
return false;
}
}
return tag;
}
var newArr=[],obj={};
for(var i=0,len=this.length;i<len;i++){
if(!sameObj(obj[typeof(this[i])+this[i]],this[i])){
newArr.push(this[i]);
obj[typeof(this[i])+this[i]]=this[i];
}
}
return newArr;
}
用上面的例子測試發(fā)現(xiàn)基本木有問題,當(dāng)然測試還可以更加變態(tài)更加糾纏,這里就不去深究了,目前來看此篇方法在網(wǎng)上屬于比較齊全的,如果有更好更完善的方法請不吝賜教。
考慮一個問題由簡到繁相對容易接受一點,首先假設(shè)要去重的數(shù)組是比較簡單的,例如:
復(fù)制代碼 代碼如下:
var arr=[1,2,2,3,'5',6,5,'',' ']
這個數(shù)組只包含了數(shù)字,字符串兩種類型。我們給數(shù)組原型上面添加去重的方法distinct,用第一種很容易想到的方法來實現(xiàn),當(dāng)然也是很笨很直接的,把這個數(shù)組復(fù)制一份然后循環(huán)兩個數(shù)組,對比當(dāng)前值與后面所有的值是否相等,如果與后面所有值都不等則把該值存到新數(shù)組里,如此最后再返回該新數(shù)組。方法如下:
復(fù)制代碼 代碼如下:
//第一種方法
Array.prototype.distinct=function(){
var clone,newArr=[],n=0;
if(this.length<2)return;
clone=this;
for(var i=0,len=this.length;i<len;i++){
for(var j=i+1,len2=clone.length;j<len2;j++){
if(this[i]!==clone[j]){
n++;
}
}
if(n==(len-i-1)){
newArr.push(this[i])
}
n=0;
}
return newArr;
}
console.log([1,2,2,3,'5',6,5,'',' '].distinct());
/*獲得被check的radio的值*/
function GetRadioValue(RadioName){
var obj;
obj=document.getElementsByName(RadioName);
if(obj!=null){
var i;
for(i=0;i<obj.length;i++){
if(obj[i].checked){
return obj[i].value;
}
}
}
return null;
}
/*設(shè)置被選中屬性*/
function SetRadioCheck(RadioName,i){
var obj;
obj=document.getElementsByName(RadioName);
obj[i].setAttribute("checked","checked");
}
基本可以滿足我們的需求,對這樣簡單的類型比較確實不用費(fèi)太多的腦經(jīng),但如果數(shù)組很長呢?如此遍歷數(shù)組,數(shù)組長度為n,那么時間復(fù)雜度為n*n。顯然該方法性能還有待提升。接下來是第二種方法,用到數(shù)組排序,在排序的過程去除重復(fù)的值。
復(fù)制代碼 代碼如下:
//第二種方法
Array.prototype.distinct=function(){
var newArr=this.concat().sort(),self=this;
newArr.sort(function(a,b){
var n;
if(a===b){
n=self.indexOf(a);
self.splice(n,1);
}
});
return self;
}
console.log([1,2,2,3,'5',6,5,6,6,15,5,'5',5,'',' '].distinct());
這樣代碼看起來似乎短了很多,甚至連一個for循環(huán)都沒有,但是sort得效率也高不到哪里去。再來看看第三種實現(xiàn)方法,用到的對象屬性不會重名的原理
復(fù)制代碼 代碼如下:
//第三種方法
Array.prototype.distinct=function(){
var newArr=[],obj={};
for(var i=0,len=this.length;i<len;i++){
if(!obj[this[i]]){
newArr.push(this[i]);
obj[this[i]]='new';
}
}
return newArr;
}
console.log([1,2,2,3,'5',6,5,6,6,15,5,'5',5,'',' '].distinct());
第三種方法運(yùn)行看下結(jié)果,會發(fā)現(xiàn)跟上面的方法實現(xiàn)的結(jié)果不一致,細(xì)看原來它把數(shù)字5和字符串5當(dāng)成重復(fù)的值給去掉了??磥眍愋捅仨毐4嫫饋砣缓笤倥袛嗍欠裣嗟?,這樣便有了下面的第三種方法的補(bǔ)充版
復(fù)制代碼 代碼如下:
//第三種方法補(bǔ)充版
Array.prototype.distinct=function(){
var newArr=[],obj={};
for(var i=0,len=this.length;i<len;i++){
if(!obj[typeof(this[i])+this[i]]){
newArr.push(this[i]);
obj[typeof(this[i])+this[i]]='new';
}
}
return newArr;
}
上面舉的例子是很簡單的類型,我們拿更復(fù)雜的類型來測試一下
復(fù)制代碼 代碼如下:
console.log([1,null,2,{a:'vc'},{},'5',6,5,6,{a:'vv'},15,5,'5',5,'',' ',[1],[1],[1,2],,].distinct());
發(fā)現(xiàn){a:'vc'},{},{a:'vv'}這些不同的對象還是會被剔除掉,如果數(shù)組里面有對象則要繼續(xù)遍歷對象里面的屬性和值,繼續(xù)第三種方法的加強(qiáng)
復(fù)制代碼 代碼如下:
//第三種方法加強(qiáng)版
Array.prototype.distinct=function(){
var sameObj=function(a,b){
var tag = true;
if(!a||!b)return false;
for(var x in a){
if(!b[x])
return false;
if(typeof(a[x])==='object'){
tag=sameObj(a[x],b[x]);
}else{
if(a[x]!==b[x])
return false;
}
}
return tag;
}
var newArr=[],obj={};
for(var i=0,len=this.length;i<len;i++){
if(!sameObj(obj[typeof(this[i])+this[i]],this[i])){
newArr.push(this[i]);
obj[typeof(this[i])+this[i]]=this[i];
}
}
return newArr;
}
用上面的例子測試發(fā)現(xiàn)基本木有問題,當(dāng)然測試還可以更加變態(tài)更加糾纏,這里就不去深究了,目前來看此篇方法在網(wǎng)上屬于比較齊全的,如果有更好更完善的方法請不吝賜教。
您可能感興趣的文章:
- js 巧妙去除數(shù)組中的重復(fù)項
- JS實現(xiàn)合并兩個數(shù)組并去除重復(fù)項只留一個的方法
- javascript 刪除數(shù)組中重復(fù)項(uniq)
- JavaScript合并兩個數(shù)組并去除重復(fù)項的方法
- javascript數(shù)字?jǐn)?shù)組去重復(fù)項的實現(xiàn)代碼
- JS實現(xiàn)的數(shù)組去除重復(fù)數(shù)據(jù)算法小結(jié)
- js數(shù)組去重的5種算法實現(xiàn)
- js取兩個數(shù)組的交集|差集|并集|補(bǔ)集|去重示例代碼
- js實現(xiàn)數(shù)組去重、判斷數(shù)組以及對象中的內(nèi)容是否相同
- 關(guān)于js數(shù)組去重的問題小結(jié)
- JS基于對象的特性實現(xiàn)去除數(shù)組中重復(fù)項功能詳解
相關(guān)文章
當(dāng)$.get返回失敗后調(diào)用fail方法示例詳解
這篇文章主要介紹了當(dāng)$.get返回失敗后,調(diào)用fail方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-12-12手把手教你實現(xiàn)一個JavaScript時間軸組件
本文主要是給大家?guī)硪粋€時間軸的組件開發(fā)教程,其主要功能就是可以拖動時間軸來定位當(dāng)前時間,可以通過鼠標(biāo)滾輪來修改當(dāng)前時間分辨率,需要的可以參考一下2022-10-10JavaScript toDataURL圖片轉(zhuǎn)換問題解讀
這篇文章主要介紹了JavaScript toDataURL圖片轉(zhuǎn)換問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-06-06