javascript下過(guò)濾數(shù)組重復(fù)值的代碼(類(lèi)似于SQL的distinct)
|
admin
2012年4月23日 21:51
本文熱度 12730
|
<script language="javascript"> function getNoRepeat() { return arguments[0].join('‖').match(/(\b[^‖]+\b)(?!.*‖\1\b)/ig); } var tmpArr = [1, 'a', 'ab', 'abc', 'd', 1.2, 'a+b', 'd', 'e', 5, 'a', 1, 'h', 'c', 'ab']; var retArr = getNoRepeat(tmpArr); alert(retArr); </script>
<script> alert("1,11,1.11,1111,111,11,1,1.11".match(/(\b\d+(?:\.\d+)?\b)(?!.*,\1\b)/g)) </script>
<script> alert("123450,0,1,2,5,3,2,12,4,1,1,123450".match(/(\b\d+\b)(?!.*,\1(,|$))/ig)) </script>
<script> alert("123450,0,1,2,5,3,2,12,4,1,1,123450".match(/(\b\d+\b)(?!(?:,[^,]+)*,\1(?:,|$))/ig)) </script>
<script> var s = "0,1,2,5,3,2,12,4,1,1,123450"; var sTmp = (","+s.split(",").reverse().join(",")+",").replace(/,([^,]+)(?=,.*,\1,)/ig, '').split(",").reverse().join(); sTmp = sTmp.substr(1, sTmp.length-2); alert(sTmp) </script>
<script> var strArr = "123450,0,1,2,5,3,2,12,4,1,1,123450".split(",") var str = "," for(i = 0; i < strArr.length; i++) { if(str.indexOf("," + strArr[i] + ",") == -1)str += strArr[i] + "," } alert(str.substring(1,str.length - 1)) </script>
該文章在 2012/4/23 21:51:03 編輯過(guò)
| |
全部評(píng)論5 |
|
admin
2012年4月23日 21:55
js數(shù)組中去除重復(fù)值
<script>
Array.prototype.del = function() {
var a = {}, c = [], l = this.length;
for (var i = 0; i < l; i++) {
var b = this[i];
var d = (typeof b) + b;
if (a[d] === undefined) {
c.push(b);
a[d] = 1;
}
}
return c;
}
alert([1, 1, 2, 3, 4, 5, 4, 3, 4, 4, 5, 5, 6, 7].del());
</script>
[Ctrl+A 全選 注:如需引入外部Js需刷新才能執(zhí)行]
方法二
復(fù)制代碼 代碼如下:
//去重復(fù)數(shù)組
function unique(data){
data = data ││ [];
var a = {};
len = data.length;
for (var i=0; i<len;i++){
var v = data[i];
if (typeof(a[v]) == 'undefined'){
a[v] = 1;
}
};
data.length=0;
for (var i in a){
data[data.length] = i;
}
return data;
}
方法三
復(fù)制代碼 代碼如下:
var arr = ["123","123","123","123","sfsdf","123","345","123","123","345","456","567","sdc"];
var str = [];
for(var i = 0,len = arr.length;i < len;i++){
! RegExp(arr[i],"g").test(str.join(",")) && (str.push(arr[i]));
}
alert(str);
方法四
復(fù)制代碼 代碼如下:
var pureMulti1=function(arr){
var obj={};
var a = [];
for(var i=0,l=arr.length;iif(!((arr[i]+"") in obj)){
a.push(arr[i]);
}
obj[arr[i]]="";
}
return a;
} 該評(píng)論在 2012/4/23 21:56:04 編輯過(guò)
|
|
admin
2012年4月23日 21:56
百度面試時(shí)問(wèn)的一道題目,蠻常規(guī)的,但是當(dāng)時(shí)自己的回答挺差勁的。現(xiàn)在總結(jié)記錄下~
代碼如下:
題目:要求寫(xiě)一個(gè)函數(shù),去掉給定數(shù)組中的重復(fù)值。
如:
傳入數(shù)組 a = [0, 8, 5, 4, 78, 8, 90, 4, 'a', 'b', 'a'];
要求返回:[0,4,5,8,78,90,a,b]
對(duì)于這個(gè)題目,在面試之后也想了好多次,不過(guò)一直沒(méi)能想出一個(gè)時(shí)間復(fù)雜度較低的方法。昨天下午在宿舍看《JavaScript語(yǔ)言精粹》看到一個(gè)書(shū)中的一段代碼有所觸發(fā),于是在jsfiddle上測(cè)試了,成功。代碼如下(完整版參見(jiàn)jsfiddle)
var getNR = function(src) {
src = src ││ [];
var res = {};
var curr = [];
var i, j = 0,temp, name;
for (i = 0; i < src.length; i++) {
temp = src[i];
if (res[temp]) {
//do noting
} else {
res[temp] = 1;
}
}
for (name in res) {
if (res.hasOwnProperty(name)) {
curr[j++] = name;
}
}
return curr;
};
總結(jié)一下我的思路:
思路一:將目標(biāo)數(shù)組進(jìn)行排序,然后依序刪除重復(fù)的數(shù)組,但這樣在刪除重復(fù)元素的同時(shí)也改變數(shù)組原有元素的屬性,明顯是不符合要求的,del。
思路二:新建一個(gè)數(shù)組b,將a中的元素push到b中,但是在push之前檢查該元素是否存在。這個(gè)時(shí)間復(fù)雜度是n*n,最簡(jiǎn)單也是最笨的辦法。
思路三:跟思路二類(lèi)似,不過(guò)充分利用了js對(duì)象的屬性,新建一個(gè)空對(duì)象,將a中的元素作為屬性添加到該對(duì)象中,在添加之前檢測(cè)該屬性是否已存在。全部添加完后將該對(duì)象的屬性依序放到數(shù)組中,return
美團(tuán)面試的題目中有一道這個(gè)題目的變種:
要求在Array類(lèi)上添加一個(gè)方法,對(duì)于任意數(shù)組調(diào)用該方法后,去除該數(shù)組中的重復(fù)元素。
這個(gè)變種題考查的知識(shí)點(diǎn)多了些,還包括原型,this的理解等。 該評(píng)論在 2012/4/23 21:57:39 編輯過(guò)
|
|
admin
2012年4月23日 22:22
三個(gè)精彩的函數(shù)~~大家收到自己的函數(shù)庫(kù)里去吧~
前兩天做一個(gè)功能的時(shí)候,為Array擴(kuò)展了三個(gè)方法,可以清除數(shù)組中的重復(fù)的值。這些值可以是字符串,或者對(duì)象~~或者其它。
在網(wǎng)上找了找其它的類(lèi)同的函數(shù)~效率和實(shí)現(xiàn)方法都比較差~哈哈~
---------------
// 數(shù)據(jù)元素唯一化, 較慢但保持元素順序
// 例: [1,2,3,2,1,8,1,6,2]
// 輸出: [1,2,3,8,6]
Array.prototype.unique = function() {
for (var j, i=0, k=this.length; i<k; i++) {
for (j=i+1; j<k; j++) {
if (this[i]===this[j] && k--) this.splice(j, 1);
}
}
}
// 數(shù)據(jù)元素唯一化, 較快但不能保持元素順序
// 例: [1,2,3,2,1,8,1,6,2]
// 輸出: [1,2,3,8,6]
Array.prototype.q_unique = function() {
for (var j, i=0, k=this.length; i<k; i++) {
for (j=i+1; j<k; j++) {
if (this[i]===this[j]) this[i]=this[--k];
}
}
this.length = k;
}
// 數(shù)據(jù)元素唯一化, 僅用于排序過(guò)的數(shù)組(并保持排序狀態(tài))
// 例: [1,2,2,4,4,5,5]
// 輸出: [1,2,4,5]
Array.prototype.s_unique = function() {
for (var j, m, i=0, k=this.length; i<k; i++, k-=m) {
for (j=i+1, m=0; j<k; j++, m++) {
if (this[i]!==this[j]) break;
}
this.splice(i, m);
}
} 該評(píng)論在 2012/4/23 22:23:57 編輯過(guò)
|
|
admin
2012年4月23日 22:24
- <script>
- //Aiming 的算法
- //---------------
- // 數(shù)據(jù)元素唯一化, 較慢但保持元素順序
- // 例: [1,2,3,2,1,8,1,6,2]
- // 輸出: [1,2,3,8,6]
- Array.prototype.unique = function() {
- for (var j, i=0, k=this.length; i<k; i++) {
- for (j=i+1; j<k; j++) {
- if (this[i]===this[j] && k--) this.splice(j, 1);
- }
- }
- }
- // 數(shù)據(jù)元素唯一化, 較快但不能保持元素順序
- // 例: [1,2,3,2,1,8,1,6,2]
- // 輸出: [1,2,3,8,6]
- Array.prototype.q_unique = function() {
- for (var j, i=0, k=this.length; i<k; i++) {
- for (j=i+1; j<k; j++) {
- if (this[i]===this[j]) this[i]=this[--k];
- }
- }
- this.length = k;
- }
- // 數(shù)據(jù)元素唯一化, 僅用于排序過(guò)的數(shù)組(并保持排序狀態(tài))
- // 例: [1,2,2,4,4,5,5]
- // 輸出: [1,2,4,5]
- Array.prototype.s_unique = function() {
- for (var j, m, i=0, k=this.length; i<k; i++, k-=m) {
- for (j=i+1, m=0; j<k; j++, m++) {
- if (this[i]!==this[j]) break;
- }
- this.splice(i, m);
- }
- }
- ///////////////////////////////////////////////////////////////////////////////////////
- //Akira的處理方法,利用Hash
- function UniqueSet()
- {
- this.HashIndex = new Array();
- this.Collection = new Array();
- UniqueSet.prototype.Add = function(obj)
- {
- if (!(obj instanceof Object)) //如果obj不是對(duì)象,那么就按照基本數(shù)據(jù)類(lèi)型(值類(lèi)型)的方式處理,注意:可能對(duì)DOM無(wú)效
- {
- if (this.HashIndex[obj] == null)
- {
- this.HashIndex[obj] = this.Collection.length;
- this.Collection.push(obj);
- }
- }
- else if (obj.UUID != null) //如果對(duì)象定義了唯一表識(shí)UUID,則用UUID作為索引來(lái)處理
- {
- if (this.HashIndex[UUID] == null)
- {
- this.HashIndex[UUID] = this.Collection.length;
- this.Collection.push(obj);
- }
- }
- else
- {
- //對(duì)象的處理辦法,利用腳本特性
- if (obj.__UniqueSet_Member_Belongs_To == null)
- obj.__UniqueSet_Member_Belongs_To = new Array();
- for (var i = 0; i < obj.__UniqueSet_Member_Belongs_To.length; i++)
- {
- if (obj.__UniqueSet_Member_Belongs_To[i] == this)
- {
- return;
- }
- }
- obj.__UniqueSet_Member_Belongs_To.push(this);
- this.Collection.push(obj);
- }
- }
- UniqueSet.prototype.toArray = function()
- {
- return this.Collection;
- }
- }
- UniqueSet.parse = function(array)
- {
- array = array.slice(0);
- var uSet = new UniqueSet();
-
- for (var i = 0; i < array.length; i++)
- {
- uSet.Add(array[i]);
- }
- return uSet.toArray();
- }
- function createObjs(size)
- {
- var objList = new Array(); //構(gòu)造測(cè)試數(shù)組
- for (var i = 0; i < size; i++) //構(gòu)造對(duì)象(這部分時(shí)間不計(jì))
- {
- if (Math.random() > rate)
- {
- item = new Object();
- item.hashCode = Math.random();
- }
- objList.push(item);
- }
- return objList;
- }
- function uniqueTest(objList)
- {
- var test = objList.slice(0); //構(gòu)造測(cè)試副本
- document.write("元素個(gè)數(shù):"+test.length+",重復(fù)率:"+rate+",開(kāi)始計(jì)時(shí)<br/>");
- var startTime = new Date().getTime(); //計(jì)時(shí)
- test.unique();
- var timeUsed = (new Date() - startTime)/1000;
- document.write("unique()耗時(shí):"+timeUsed+"秒,不重復(fù)元素個(gè)數(shù)"+test.length+"個(gè)<br/>");
- }
- function q_uniqueTest(objList)
- {
- var test = objList.slice(0); //構(gòu)造測(cè)試副本
- document.write("元素個(gè)數(shù):"+test.length+",重復(fù)率:"+rate+",開(kāi)始計(jì)時(shí)<br/>");
- var startTime = new Date().getTime(); //計(jì)時(shí)
- test.q_unique();
- var timeUsed = (new Date() - startTime)/1000;
- document.write("q_unique()耗時(shí):"+timeUsed+"秒,不重復(fù)元素個(gè)數(shù)"+test.length+"個(gè)<br/>");
- }
- function uSetTest(objList)
- {
- var test = objList.slice(0);
- document.write("元素個(gè)數(shù):"+test.length+",重復(fù)率:"+rate+",開(kāi)始計(jì)時(shí)<br/>");
- var startTime = new Date().getTime(); //計(jì)時(shí)
- test = UniqueSet.parse(test);
- var timeUsed = (new Date() - startTime)/1000;
- document.write("uSet()耗時(shí):"+timeUsed+"秒,不重復(fù)元素個(gè)數(shù)"+test.length+"個(gè)<br/><br/>");
- }
- //測(cè)試開(kāi)始...
- var rate = 0.1; //元素重復(fù)率
- var item = new Object(); //要插入的元素
- item.hashCode = Math.random(); //沒(méi)有別的意義,單純的標(biāo)識(shí)
- var objList = createObjs(500); //構(gòu)造一個(gè)500隨機(jī)對(duì)象的數(shù)組
- //下面開(kāi)始測(cè)試排序:
- uniqueTest(objList);
- q_uniqueTest(objList);
- uSetTest(objList);
- objList = createObjs(800); //增加到800對(duì)象
- uniqueTest(objList);
- q_uniqueTest(objList);
- uSetTest(objList);
- objList = createObjs(1000); //增加到1000對(duì)象
- uniqueTest(objList);
- q_uniqueTest(objList);
- uSetTest(objList);
- document.write("后面因?yàn)锳iming的算法速度太慢,而IE提示會(huì)影響計(jì)時(shí),所以不得不停止測(cè)試,僅用我的算法計(jì)時(shí)<br/>");
- //objList = createObjs(1200); //增加到1200對(duì)象
- //uSetTest(objList);
- objList = createObjs(1500); //增加到1500對(duì)象
- uSetTest(objList);
- document.write("很奇怪地發(fā)現(xiàn)我寫(xiě)的算法得到的結(jié)果和Aiming寫(xiě)的兩個(gè)算法分別得到的結(jié)果居然都不一樣??結(jié)果:隨便測(cè)試了一下...<br/>");
- var testArray = new Array(10,20,30,30,30,40,20,10,4);
- test = testArray.slice(0);
- test.unique();
- document.write("居然檢測(cè)出了Aiming的unique()函數(shù)的這個(gè)錯(cuò)誤結(jié)果:<br/>原始數(shù)組:"+testArray+"<br/>結(jié)果數(shù)組:"+test+"<br/>=.=...汗...<br/>");
- </script>
復(fù)制代碼運(yùn)行代碼另存代碼
應(yīng)該說(shuō),樓主寫(xiě)的函數(shù)從代碼的角度來(lái)講,還算是不錯(cuò)的,但是有下面的一些問(wèn)題:
1) 沒(méi)有保存原始的數(shù)組對(duì)象,既然改寫(xiě)(增加)了數(shù)組的方法,那么應(yīng)該保護(hù)原始的數(shù)組對(duì)象,否則的話array.unique()的時(shí)候破壞掉了原來(lái)的數(shù)組。
像array.slice()等系統(tǒng)庫(kù)函數(shù)這方面就做得比較好,樓主可以參考。
除非樓主是打算做成像array.push()或者array.splice()之類(lèi)的“寫(xiě)操作”方法,不過(guò)我個(gè)人認(rèn)為將unique方法做成寫(xiě)方法的話應(yīng)用價(jià)值就打折扣了。
2)方法的效率不是很高,一個(gè)簡(jiǎn)單的測(cè)試如上...大概算到1000數(shù)量級(jí)的時(shí)候就不大行了。我利用腳本語(yǔ)言的特性寫(xiě)了實(shí)現(xiàn)同樣功能的方法,效率會(huì)比較高一點(diǎn)。
腳本是解釋型語(yǔ)言,弱點(diǎn)是效率比較低,但是同時(shí)也帶來(lái)一些靈活的特性(例如動(dòng)態(tài)增加屬性),活用它們可以彌補(bǔ)弱點(diǎn)。
3)一個(gè)更為致命的問(wèn)題是頭兩個(gè)方法都有BUG,第三個(gè)方法我沒(méi)有測(cè)試,不知道是否正確。第一個(gè)方法(unique())居然連new Array(10,20,30,30,30,40,20,10,4);這樣簡(jiǎn)單的Case都沒(méi)有通過(guò),建議樓主再修改一下。
最后我要說(shuō),腳本語(yǔ)言雖然簡(jiǎn)單,然而因?yàn)樽杂桑褂闷饋?lái)也有各種復(fù)雜的變化。如何發(fā)揮它們的優(yōu)勢(shì),彌補(bǔ)不足,其實(shí)這其中的道理并不簡(jiǎn)單。
作為程序語(yǔ)言的一種,腳本語(yǔ)言也是“道”的一部分。在求“道”的過(guò)程中應(yīng)當(dāng)多多深入探索,才會(huì)有所領(lǐng)悟,許多東西并不像表面那么簡(jiǎn)單。在我看來(lái),樓主的代碼也僅能算做勉強(qiáng)合格(去除BUG之后),所以我想勸樓主收回“精彩”二字以及后面那句話 :P
停止一些浮躁的舉動(dòng),靜下心來(lái)認(rèn)真學(xué)習(xí)和研究,往往會(huì)有很多意想不到的收獲。 該評(píng)論在 2012/4/23 22:26:54 編輯過(guò)
|
|
admin
2012年4月23日 22:25
對(duì)了,各位在運(yùn)行上面那個(gè)例子的時(shí)候如果IE彈出了運(yùn)行速度慢的提示的話,那么最后一個(gè)(也可能是倒數(shù)第二個(gè),具體要看提示框彈出的時(shí)間)時(shí)間就不準(zhǔn)確了...(因?yàn)橛涗浀臅r(shí)間還包括點(diǎn)擊確定按鈕關(guān)閉對(duì)話框的時(shí)間)
其實(shí)主要還是因?yàn)闇y(cè)試用例動(dòng)態(tài)創(chuàng)建隨機(jī)大數(shù)組浪費(fèi)了非常多的時(shí)間,如果單獨(dú)使用的話,我的算法大概可以跑在高于10000數(shù)量級(jí)上,如果,數(shù)組元素是簡(jiǎn)單類(lèi)型而不是對(duì)象的話,還可以再提高一個(gè)數(shù)量級(jí),但那也不是最好的算法,相信還有很多個(gè)優(yōu)秀的算法實(shí)現(xiàn)...
總體來(lái)說(shuō),javascript是非常自由的...
所以充分發(fā)揮想象和創(chuàng)造往往可以獲得“令人驚嘆”的代碼...
如果真正能做到,是非常令人佩服的(那種大牛是月影追求的目標(biāo)^^)
而能夠欣賞到那樣的代碼也是非常幸運(yùn)的
因?yàn)槟且彩且环N程序界的“藝術(shù)”和“美” ^^
|
|
|