比如有一个数组arr[1,3,2,3,5,4,2,7],我想把元素个数大于1的都去掉,得到的结果是arr[1,5,4,7],而不是arr[1,3,2,5,4,7],请问怎么用js实现,效率越快越好。
给你看一种实现:
arr = [1,3,2,3,5,4,2,7] var m = {}, result = []; arr.forEach(function(obj, i){ m['' + obj] = (m['' + obj] || 0) + 1; }); for(var p in m){ if(m[p]===1){ result.push(+p); } } result;
console.time('t1') for(var count = 0; count < 1000; count++){ var arr = [1,3,2,3,5,4,2,7]; var m = {}, result = []; arr.forEach(function(obj, i){ m['' + obj] = (m['' + obj] || 0) + 1; }); for(var p in m){ if(m[p]===1){ result.push(+p); } } result; } console.timeEnd('t1') Array.prototype.hasValueCount = function(value){ var count = 0; for(var i = 0, len = this.length; i < len; i ++){ if(this[i] === value) { count++; } } return count; }; console.time('t2') for(var count = 0; count < 1000; count++){ var arr = [1,3,2,3,5,4,2,7]; var result = []; arr.forEach(function(obj, i){ if(arr.hasValueCount(obj) === 1){ result.push(obj); } }); result; } console.timeEnd('t2') 包含小数据的性能测试。
@幻天芒: 好的,多谢,我看看。
@幻天芒:
m[obj] 为什么要写成这样?
m['' + obj]
@ayiis: 转换为字符串key,如果是整数的话,会被当成索引。
往新数组里放
关键是在放的时候得判断当前元素是否存在吧?,重复项的第一个以后的元素能判断是否存在,但是第一个重复项放的时候肯定不存在,那不是就放进去了?
@冷水寒冰: 做个判断。如果为第一项则放进去。
@冷水寒冰: 遍历新数组,不存在的就放进去。
@zuike: 第一项放进去的话我后边怎么去除?
采用hash形式 在数据量很大的时候 效率就很明显
Test1:
1 function Test1() { 2 var hashArr = {}, tempArr = []; //hashArr为hash表,tempArr为临时数组 3 var arr = [1, 3, 2, 3, 5, 4, 2, 7]; 4 var d11 = new Date(); 5 var st = d11.getTime(); 6 for (var j = 0; j < 1000000; j++) { 7 for (var i = 0,len=arr.length; i < len; i++) 8 { 9 if (!hashArr[arr[i]]) 10 { 11 hashArr[arr[i]] = true; 12 tempArr.push(this[i]); 13 } 14 } 15 } 16 var d12 = new Date(); 17 var et = d12.getTime(); 18 alert("Test1 Length:" + tempArr.length + " And Time:" + (et - st) / 1000); 19 }
结果如下:
Test2:(幻天芒的方法对比)
1 function Test2() 2 { 3 var arr = [1, 3, 2, 3, 5, 4, 2, 7]; 4 var m = {}, result = []; 5 var d21 = new Date(); 6 var startTime = d21.getTime(); 7 for (var count = 0; count < 1000000; count++) { 8 arr.forEach(function (obj, i) { 9 m['' + obj] = (m['' + obj] || 0) + 1; 10 }); 11 for (var p in m) { 12 if (m[p] === 1) { 13 result.push(+p); 14 } 15 } 16 } 17 var d22 = new Date(); 18 var endTime = d22.getTime(); 19 alert("Test2 Length:" + result.length + " And Time:" + (endTime - startTime) / 1000); 20 }
结果:
由此看出 Test1 比Test2强,结果数量 Test1 要正确些
你没坑我?而且你的结果也不太对。
请看以下的完整测试代码:
var arr = [1, 3, 2, 3, 5, 4, 2, 7]; var testCount = 100000; Array.prototype.hasValueCount = function(value){ var count = 0; for(var i = 0, len = this.length; i < len; i ++){ if(this[i] === value) { count++; } } return count; }; //测试一 console.time('t1'); for (var j = 0; j < testCount; j++) { var hashArr = {}, tempArr = []; //hashArr为hash表,tempArr为临时数组 for (var i = 0,len=arr.length; i < len; i++) { if (!hashArr[arr[i]]) { hashArr[arr[i]] = true; tempArr.push(this[i]); } } } console.timeEnd('t1'); //测试二 console.time('t2'); var m = {}, result = []; for (var count = 0; count < testCount; count++) { arr.forEach(function (obj, i) { m['' + obj] = (m['' + obj] || 0) + 1; }); for (var p in m) { if (m[p] === 1) { result.push(+p); } } } console.timeEnd('t2') //测试三 console.time('t3') for(var count = 0; count < testCount; count++){ var result = []; arr.forEach(function(obj, i){ if(arr.hasValueCount(obj) === 1){ result.push(obj); } }); } console.timeEnd('t3')
从结果来看,当testCount=1000(较小)时,方案三是三者中最快的。当testCount = 1000000(较大)时,方案二是三者中最快的。
以上代码可直接复制到Chrome控制台执行。
倒序遍历,删除大于1的元素。
1 var arr=[1,3,2,3,5,4,2,7]; 2 for(var i=arr.length-1,i>=0;i--) 3 { 4 if(arr[i]>1) 5 { 6 arr.remove(i); 7 } 8 }