js去重的几种方法:
1.使用indexOf()方法---[a.检查当前数组是否存在;b.比较数组的下标---(借助新数组,原数组)]
2.for内外双层循环
3.先排序后去重---不考虑原数组的顺序时可以考虑使用
4.对象键值法去重(速度快,但占内存大,空间换时间)
- 方法一 使用indexOf()方法判断当前数组的元素是否存在,不存在就存进新的数组,否则跳过。
注意indexOf方法是es5的新特性 不兼容ie8及以下的版本
var arr = [3,1,2,1,1,3,4,5,6,7];
console.log(arr);
function req1(arr){
var newarr = []; //新建临时数组
for(var i = 0; i < arr.length; i++){
//如果当前数组的第i已经保存进了临时数组,那么跳过,
//否则把当前项push到临时数组里面
if (newarr.indexOf(arr[i]) == -1) newarr.push(arr[i]);
}
return newarr;
}
console.log(req1(arr)) //[3, 1, 2, 4, 5, 6, 7]
- //方法二 数组下标 通过indexOf方判断当前元素在数组中的索引如果与循环的下标相等则添加到新数组中
//实现思路:如果当前数组的第i项在当前数组中第一次出现的位置不是i,那么表示第i项是重复的,忽略掉。否则存入结果数组。
//性能跟方法1差不多,
function rep2(arr) {
var newarr = [];
for (var i = 0; i < arr.length; i++) {
if (arr.indexOf(arr[i]) == i) newarr.push(arr[i]);
}
return newarr;
}
console.log(rep2(arr)); //[3, 1, 2, 4, 5, 6, 7]
- //方法三 在原来的数组上 借助indexOf()方法判断此元素在该数组中首次出现的位置下标与循环的下标不相等则删除掉
function rep3(arr) {
for (var i = 0; i < arr.length; i++) {
if (arr.indexOf(arr[i]) != i) {
arr.splice(i,1);//删除数组元素后数组长度减1后面的元素前移
i--;//数组下标回退
}
}
return arr;
}
console.log(rep3(arr)); //[3, 1, 2, 4, 5, 6, 7]
- //方法四 常规方法 新旧数组都需要进行循环,因此效率比较低
var arr = ['d','b','c',1,2,3,'a','b']
// console.log(arr)
function rep4(arr) {
var newarr = [arr[0]] //这里构建一个newarr数组 且存放了第一个值 以便下面对比
for (var i= 1; i< arr.length; i++) {
var isrepeat = false
for (var j= 0; j< newarr.length; j++) { //循环两个数组做对比
if(arr[i] == newarr[j]) {
isrepeat = true
break //这里判断下循环arr时候跟newarr对比 相等就跳出 且给出标记 当前arr数组第几个是出现重复的
}
}
if (!isrepeat) {
newarr.push(arr[i]) //这里 true标记的都是重复的 false都是可以添加的
}
}
return newarr //返回
}
console.log(rep4(arr)) //["a", "b", "c", 1, 2, 3]
- //方法五 排序后去重
//实现思路:给传入数组排序,排序后相同值相邻,然后遍历时 就比较原数组的元素和新数组最后一个元素是否相同。
//缺点:改变了原数组的顺序
// 将相同的值相邻,然后遍历去除重复值
var arr = ['e','a','b',1,2,3,'a','b'];
function rep5(array){
array.sort();
var newarr=[array[0]]; //构建一个newarr数组 存放原数组第一个元素
for(var i = 1; i < array.length; i++){
if( array[i] !== newarr[newarr.length-1])
{
newarr.push(array[i]);
}
}
return newarr;
}
console.log(rep5(arr)) //[1, 2, 3, "a", "b", "e"]
- //方法六 对象键值法去重(推荐使用)
//速度最快, 占空间最多(空间换时间)
//思路:新建一js对象以及新数组,遍历传入数组时,判断值是否为js对象的键,不是的话给对象新增该键并放入新数组。
var arr = ['f', '0', '3', '2', 'd', 'd',0,2]
function rep6(arr) {
var newarr = [] //构建newarr 数组
var obj = {} //构建一个对象obj
for (var i= 0; i< arr.length; i++) {
if (!obj[arr[i]]) { //如果元素跟数组对比
newarr.push(arr[i])
obj[arr[i]] = 1 // 元素内容作为对象属性,不为0就行
//将当前数组的这个属性设置一个值表示对象中有了这个值
}
}
return newarr
}
console.log(rep6(arr)) //["f", "0", "3", "2", "d"]
//注意点:判断是否为js对象键时,会自动对传入的键执行“toString()”,JS 的键是不分类型的
//不同的键可能会被误认为一样,例如n[val]-- n[1]、n["1"];
//解决上述问题还是得调用“indexOf()”。如果要区分数字和字符串,就要保存类型
//理解:当遍历到一个新值 val,问题中的代码会检查 val 是否在 obj 的键中,然后检查 val 的类型是否在 val 键对应的值中,两种皆否则认定这是一个非重复的值。
function rep6_1(array){
var obj = {}, newarr = [], len = array.length, val, type;
for (var i = 0; i < array.length; i++) {
val = array[i];
type = typeof val; //判断val类型
//1.判断val是否在obj的键中;2.判断val的类型是否在val键对应的值中。找不到返回-1
if (!obj[val]) {
obj[val] = [type];
newarr.push(val);
} else if (obj[val].indexOf(type) < 0) {
//返回的结果是true 小于0是正确的
obj[val].push(type);
newarr.push(val);
}
}
return newarr;
}
console.log(rep6_1(arr)) //["f", "0", "3", "2", "d", 0, 2]
- //方法七 是四的优化
//实现思路:获取没重复的最右一值放入新数组。(检测到有重复值时终止当前循环同时进入顶层循环的下一轮判断)
//可以辨别0 和 “0” 比方法六的方法还优化
var arr = ['g', '0', '3', '2', 'd', 'd',0]
function rep7(array){
var r = [];
var len = array.length;
for(var i = 0;i < len; i++) {
for(var j = i + 1; j < len; j++){
if (array[i] === array[j]) j = ++i;
}
r.push(array[i]);
}
return r;
}
console.log(rep7(arr)) ////["g", "0", "3", "2", "d"]