在某网课学习前端笔记整理js篇22-类数组ArrayLike、数组的长度是会去动态的改变的、去除数组重复数据多种方法

类数组ArrayLike、数组的长度是会去动态的改变的、去除数组重复数据多种方法

一、类数组ArrayLike

参照:https://www.cnblogs.com/guorange/p/6668440.html。

如果类数组的length和属性乱七八糟的?

1.啥叫类数组?
  • 拥有length属性,其它属性(索引)为非负整数(对象中的索引会被当做字符串来处理,这里你可以当做是个非负整数串来理解)的对象。

  • 不具有数组所具有的方法。

    类数组转为数组可以使用数组的很多方法。

example1

//类数组示例
var a = {'1':'a','2':'b','5':'c',length:5};

example2

//判断是否是类数组
function isArrayLike(o) {
    if (o &&                                // o is not null, undefined, etc.
        typeof o === 'object' &&            // o is an object
        isFinite(o.length) &&               // o.length is a finite number
        o.length >= 0 &&                    // o.length is non-negative
        o.length===Math.floor(o.length) &&  // o.length is an integer
        o.length < 4294967296)              // o.length < 2^32
        return true;                        // Then o is array-like
    else
        return false;                       // Otherwise it is not
}

​ js中常见的类数组有arguments对象和DOM方法返回的结果。

​ 比如document.getElementsByTagName().

2.类数组转为数组的方法

example3

var arraylike = {'1':'a','2':'b','5':'c',length:5};

var arr = Array.prototype.slice.call(arraylike);
console.log(arr);//[empty, "a", "b", empty × 2]

arr = [].slice.call(arraylike);
console.log(arr);//[empty, "a", "b", empty × 2]

arr = [].splice.call(arraylike,0);
console.log(arr);//[empty, "a", "b", empty × 2]

​ 方法不唯一,这里只是将数组的slice方法的this指针替换了,然后将类数组作为原来的数组来执行slice等方法。灵位可以发现类数组丢失了一个属性,所以不是所有类数组转为数组都是完整的,属性大小不能超出或等于length的长度(我猜的)。不过一般都可以。

slice方法的内部实现如下:

example4

//slice的内部实现
Array.prototype.slice = function(start,end){  
      var result = new Array();  
      start = start || 0;  
      end = end || this.length; //this指向调用的对象,当用了call后,能够改变this的指向,也就是指向传进来的对象,这是关键  
      for(var i = start; i < end; i++){  
           result.push(this[i]);  
      }  
      return result;  
 } 
3.数组转为类数组

example5

function convertArrayLike(arr){
    var obj = arr.reduce(function(prev,cur,curindex,array){ 
        return prev[curindex] = cur,prev;
    },{});
    return obj.length = arr.length,obj;
}
var arr = [1,2,3,1,2,6];
console.log(convertArrayLike(arr));//{0: 1, 1: 2, 2: 3, 3: 1, 4: 2, 5: 6, length: 6}

二、数组的长度是会去动态的改变的

看一个问题,如下:

example6

var arr = [1,2,3,4,5];
for(var i = 0;i < arr.length;i++){
    //删除第i+1个元素(删除第i个元素起的1个元素,返回删除的元素数组)
    arr.splice(i, 1);
}
console.log(arr);//[2, 4]

​ 这里我们想删光所有数组元素,但结果却不是想象的那样,因为数组删掉一个元素后,可能会对下一步循环的寻找的元素有影响,解决方法如下:

example7

var arr = [1,2,3,4,5];
for(var i = arr.length;i  > 0;i--){
    //删除最后一个元素
    arr.splice(i-1, 1);
}
console.log(arr);//[]

三、去除数组重复数据多种方法

思维锻炼

example8

function unique(arr){
    for(var i = 0;i < arr.length;i++){
        for(var j = arr.length-1;j > i;j--){
            arr[i] === arr[j] ? arr.splice(j,1):null;
        }
    }
}
var arr = [1,2,3,4,3,2,1];
unique(arr)||console.log(arr);// [1, 2, 3, 4] unique()方法返回undefined,即为false

两边遍历,删掉重复的右边。不过这个方法会改变原有的数组。

example9

function unique(arr){
    var temp = [];
    for(var i = 0;i < arr.length;i++){
        for(var j = 0;j < temp.length;j++){
            if(arr[i] === temp[j]) break;
        }
        if(temp.length == j){
            temp.push(arr[i]);
        }
    }
    return temp;
}
var arr = [1,2,3,3,3,2,1];
var arr2 = [];
console.log(unique(arr))//[1,2,3]
console.log(unique(arr2));//[]

没啥说的。

example10

function unique(arr){
    var temp = [];
    for(var i = 0;i < arr.length;i++){
        if(temp.indexOf(arr[i]) == -1) 
            temp.push(arr[i]);
    }
    return temp;
}
var arr = [1,2,3,3,3,2,1];
var arr2 = [];
console.log(unique(arr))//[1, 2, 3]
console.log(unique(arr2));//[]

这里用了数组的indexOf方法,所以在ie低版本有兼容问题。

example11

function unique(arr){
    return arr.filter(function(item,index,array){
        // return index == array.lastIndexOf(item);
        return array.indexOf(item,index+1) == -1;
    });
}
var arr = [1,2,3,3,3,2,1];
var arr2 = [];
console.log(unique(arr))//[3, 2, 1]
console.log(unique(arr2));//[]

第二个return是将最右边的重复的保留。

example12

function unique(arr){
    return arr.sort(function(a,b){
        return a-b;
    }).filter(function(item,index,array){
        return item != array[index+1];
    });
}
var arr = [1,2,3,3,3,2,1];
var arr2 = [];
console.log(unique(arr))//[1, 2, 3]
console.log(unique(arr2));//[]

先排序,再将最右边(最右边特征是与他的下一个元素不等)的过滤出来。

example13

function unique(arr){
    var obj =  {};
    return arr.filter(function(item,index,array){
        return obj[item] ? false : obj[item] = true ;
    },{});
}
var arr = [1,2,3,3,3,2,1];
var arr2 = [];
console.log(unique(arr))//[1, 2, 3]
console.log(unique(arr2));//[]

利用对象的特性过滤重复属性。

example14

function unique(arr){
    return Array.from(new Set(arr));
}
var arr = [1,2,3,3,3,2,1];
var arr2 = [];
console.log(unique(arr))//[1, 2, 3]
console.log(unique(arr2));//[]

利用set的特性(不可重复)去重。

综上,所有方法中,第1,2和最后一个兼容性较好。

发布了27 篇原创文章 · 获赞 0 · 访问量 216

猜你喜欢

转载自blog.csdn.net/qq_34338676/article/details/104715766