声明:
本文给出的大多数方法都不是原创,在具体方法使用时给出了出处的链接,不过有部分方法实现较简单很多地方都有,所以未注明,在最后会给出所有的参考链接。文章来自个人博客, 转载请注明出处。
需求:
给定一个数组,里面有重复的数字,字符串,或者是二维的数组、对象等,将里面的重复的去除,并返回新数组
针对数字及字符串的方法
测试数组为: var arr = [1, 7, 7, 1, '1',3, 5, 3, '3', '5'];
方法一
思路:用两个for循环,相互比较然后去掉重复的数字。
实现:
var arr = [1, 7, 7, 1, '1',3, 5, 3, '3', '5'];
var uniqArray1 = function(arr) {
var uniqArr = [];
var arrLen = arr.length;
for(var i = 0; i < arrLen; i++) {
for(var j = i + 1; j < arrLen; j++) {
if(arr[i] == arr[j]) {
j = ++i;
}
}
uniqArr.push(arr[i]);
}
return uniqArr;
};
console.log(uniqArray1(arr));
//[ 7, '1', '3', '5' ]
方法一容易想到,但是当测试数据很多时,由于双重循环会导致性能很差。
方法二
思路:新建数组,遍历原数组,检测当新数组中不存在原数组中的元素时将其push进去,最后返回新数组
实现:
var arr = [1, 7, 7, 1, '1',3, 5, 3, '3', '5'];
var uniqArray2 = function(arr) {
var newArr = [];
for(var i = 0,arrLen = arr.length; i < arrLen; i++) {
//indexOf在IE8一下不支持
if(newArr.indexOf(arr[i]) == -1) {
newArr.push(arr[i]);
}
}
return newArr;
};
console.log(uniqArray2(arr));
//[ 1, 7, '1', 3, 5, '3', '5' ]
比方法一的性能好一些,但是对于需要考虑IE6-8的,需要额外再加点代码:
//该代码来自:http://www.cnblogs.com/wteam-xq/p/4732351.html
//判断浏览器是否支持indexOf ,indexOf 为ecmaScript5新方法 IE8以下(包括IE8, IE8只支持部分ecma5)不支持
if (!Array.prototype.indexOf){
// 新增indexOf方法
Array.prototype.indexOf = function(item){
var result = -1, a_item = null;
if (this.length == 0){
return result;
}
for(var i = 0, len = this.length; i < len; i++){
a_item = this[i];
if (a_item === item){
result = i;
break;
}
}
return result;
}
}
方法三
思路:利用sort方法排序,然后比较数组中前后两个数字是否相同,去掉不相同的返回新数组
实现:
var arr = [1, 7, 7, 1, '1',3, 5, 3, '3', '5'];
var uniqArray3 = function(arr) {
arr.sort();
var newArr = [arr[0]];
for(var i = 1, arrLen = arr.length; i < arrLen; i++) {
if( arr[i] != newArr[newArr.length- 1]) {
newArr.push(arr[i]);
}
}
return newArr;
};
console.log(uniqArray3(arr));
//[ 1, 3, 5, 7 ]
一个关于sort方法的小插曲:
关于sort方法需要补充一点,如果需要利用sort进行升序或降序排列,为了实现排序,
sort()方法会调用每个数组项的toString()转型方法,然后比较得到的字符串确定如何排序,例如:
var values = [1,10,5,65,666,223];
values.sort();
console.log(values);
//[ 1, 10, 223, 5, 65, 666 ]
即使数组中每一项都是数值,sort()比较的也是字符串,而在比较字符串时"10"位于"5"前面,于是数组的顺序就不是预期的了。
sort可以接受一个比较函数,进而达到我们预期的比较结果:
function compare(a , b) {
if( a < b) {
return -1;
}else if(a>b) {
return 1;
}else {
return 0;
}
}
var values = [1,10,5,65,666,223];
values.sort(compare);
console.log(values);
//[ 1, 5, 10, 65, 223, 666 ]
这样就得到了升序排列,而想要降序时,只需要在打印时reverse()一下即可。
方法四
思路:利用对象中是否有一样的属性进行比较。
实现:
//from:http://blog.jobbole.com/33099/
var arr = [1, 7, 7, 1, '1',3, 5, 3, '3', '5'];
var uniqArray4 = function(arr) {
var result = [];
var hash = {};
var item,key;
for(var i = 0, arrLen = arr.length; i < arrLen; i++) {
item = arr[i];
//对象的键值只能是字符串,
key = typeof(item) + item; //区分数值 1 和字符串 '1' 等情况
if(!hash[key]) {
result.push(item); //hash用来反射key是否重复
hash[key] = true; //表明该值存进新数组了
}
}
return result;
};
console.log(uniqArray4(arr));
//[ 1, 7, '1', 3, 5, '3', '5' ]
方法五
思路:利用对象字面量的key和value关联性,
实现:
//from: https://segmentfault.com/q/1010000000262609
var arr = [1, 7, 7, 1, '1',3, 5, 3, '3', '5'];
var uniqArray5 = function(arr) {
var obj = {};
var len = arr.length;
for(var i = 0; i < len; i++) {
obj[arr[i]] = arr[i];
}
return Object.keys(obj);
};
console.log(uniqArray5(arr));
//[ '1', '3', '5', '7' ]
方法六
思路:利用数组的filter方法
实现:
//from: https://segmentfault.com/q/1010000003864059
var arr = [1, 7, 7, 1, '1',3, 5, 3, '3', '5'];
var uniqArray6 = function(arr) {
return arr.filter(function (elem, index) {
return arr.indexOf(elem) === index;
});
};
console.log(uniqArray6(arr));
//[ 1, 7, '1', 3, 5, '3', '5' ]
对于filter()方法的补充:
filter: 对数组中的每一个元素调用参数中指定的过滤函数,并将对于过滤函数返回值为true的那些数组元素集合为新的数组返回。
方法七
思路:利用数组的filter方法
var arr = [1, 7, 7, 1, '1',3, 5, 3, '3', '5'];
var uniqArray8 = arr.filter(function(element, index,array) {
return array.indexOf(element) >= index;
});
console.log(uniqArray8);
//[ 1, 7, '1', 3, 5, '3', '5' ]
方法八
思路:利用数组的filter方法
var arr = [1, 7, 7, 1, '1',3, 5, 3, '3', '5'];
var uniqArray9 = arr.filter(function(element, index,array) {
return arr.lastIndexOf(element) === index;
});
console.log(uniqArray9);
//[ 7, 1, '1', 5, 3, '3', '5' ]
方法九
思路:利用reduce方法
var arr = [1, 7, 7, 1, '1',3, 5, 3, '3', '5'];
var uniqArray8 = function(a) {
return a.reduce(function(p, c) {
if (p.indexOf(c) < 0) p.push(c);
return p;
}, []);
};
console.log(uniqArray8(arr));
//[ 1, 7, '1', 3, 5, '3', '5' ]
关于reduce方法的补充:
reduce()方法从数组的第一项开始,在每一项上调用函数,这个函数返回的任何值都会作为第一个参数自动传给下一项。
方法十
使用ES6的set方法。
Array.prototype.getUnique = function() {
return [...new Set( [this] )];
};
方法十一
使用jQuery
实现:
//from:http://stackoverflow.com/questions/1960473/unique-values-in-an-array
(function($){
var _old = $.unique;
$.unique = function(arr){
if (!!arr[0].nodeType){
return _old.apply(this,arguments);
} else {
return $.grep(arr,function(v,k){
return $.inArray(v,arr) === k;
});
}
};
})(jQuery);
var arr = ['first',7,true,2,7,true,'last','last'];
$.unique(arr);
// ["first", 7, true, 2, "last"]
var arr = [1,2,3,4,5,4,3,2,1];
$.unique(arr);
// [1, 2, 3, 4, 5]
针对二维数组的去重方法
思路:通过isArray方法判断数组中是否还有数组,如果有数组,在该数组上再次遍历
实现:
//from: https://segmentfault.com/q/1010000000444289
var arr = [1,2,3,[1,1,2],[3,2],2];
var uniqArray11 = function(arr) {
var result = arr.reduce(function(v, i) {
//判断有没有二维数组
if(Array.isArray(i)) {
i.forEach(function(item) {
if(v.indexOf(item) < 0) {
v.push(item);
}
});
}else if(v.indexOf(i) < 0){
v.push(i);
}
return v;
}, []);
return result;
};
console.log(uniqArray11(arr));
//[ 1, 2, 3 ]
针对对象的去重方法
实现:
//from:http://stackoverflow.com/questions/1960473/unique-values-in-an-array
Array.prototype.getUnique = function() {
var hash = {}, result = [], key;
for ( var i = 0, l = this.length; i < l; ++i ) {
key = JSON.stringify(this[i]);
if ( !hash.hasOwnProperty(key) ) {
hash[key] = true;
result.push(this[i]);
}
}
return result;
};
var data = [
{
name: "aaa",
value: 123
},
{
name: "bbb",
value: 234
},
{
name: "aaa",
value: 123
},
{
name: "bbb",
value: 789
}
];
console.log(data.getUnique());
//[ { name: 'aaa', value: 123 },
// { name: 'bbb', value: 234 },
// { name: 'bbb', value: 789 } ]
文章参考链接
下面是本文所述方法的来源链接:
http://www.cnblogs.com/wteam-xq/p/4732351.html
http://blog.jobbole.com/33099/
https://segmentfault.com/q/1010000000262609
https://segmentfault.com/q/1010000003864059
https://segmentfault.com/q/1010000000444289
http://stackoverflow.com/questions/1960473/unique-values-in-an-array
http://stackoverflow.com/questions/11246758/how-to-get-unique-values-in-an-array
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。