数组API和部分API的重构

101 阅读4分钟

数组的API和部分API的重构

1、push: //可以在数组的尾部添加若干个元素,返回值为新数组的长度

            var arr=[1];
            var len=arr.push(5,6,7,8);
            console.log(len);
        //循环给尾部添加若干个元素 
            while(arr.push({})<10);
            arr[0].a=10;
            console.log(arr); 

        //重构!
            function push(arr){
                for(var i=1;i<arguments.length;i++){
                    arr[arr.length]=arguments[i];
                }
                return arr.length;
            }
            var arr=[];
            var len=push(arr,1,2,3);
            console.log(len,arr);

2、pop: //删除数组尾部的最后一个元素,并且将删除的元素返回

            var element=arr.pop();
            console.log(element,arr);

            while(arr.pop()!==3);//删除到某元素为止
            console.log(arr);
        //如果数组中存储的是对象,我们必须将所有的对象引用全部设为null(引用关系)
            while(arr.length>0){
                arr[arr.length-1]=null;
                arr.pop();
            }
            有种效率更高的方法
            for(var i=0;i<arr.length;i++){
                arr[i]=null;
            }
            arr.length=0;
        //重构!
            function pop(arr){
                var elem=arr[arr.length-1];
                if(arr.length>0)arr.length--;
                return elem;
            }

3、unshift //在数组的头部添加若干个元素,并且返回这个数组的新长度

            var len=arr.unshift(5,6)
        //重构!方案1
            function unshift(arr){
                var len=arguments.length-1;
                for(var i=arr.length-1;i>=0;i--){
                    arr[i+len]=arr[i];
                    arr[i]=null;
                }
                for(var j=1;j<arguments.length;j++){
                    arr[j-1]=arguments[j];
                }
                return arr.length;
            }
        //方案2
            function unshift(arr){
                var arr1=[];
                for(var i=0;i<arr.length;i++){
                    arr1[i]=arr[i];
                }
                arr.length=0;
                for(var j=1;j<arguments.length;j++){
                    arr[j-1]=arguments[j];
                }
                for(var k=0;k<arr1.length;k++){
                    arr[arr.length]=arr1[k];
                }
                return arr.length;
            }

4、shift //将数组的头部一个元素删除,并且返回这个元素

            var elem=arr.shift();
        //重构!
            function shift(arr){
                var elem=arr[0];
                for(var i=1;i<arr.length;i++){
                    arr[i-1]=arr[i];
                }
                if(arr.length>0)arr.length--;
                return elem;
            }
//unshift和shift两个方法很少使用,因为从头增加删除元素会导致整个数组向前或向后,时间复杂度较高
//这四种方法,操作后原数组的引用关系不变

5、join //使用某个字符作为连接符,将所有数组的元素链接成为一个字符串并且返回这个字符串,如果没有连接符,则默认逗号链接

            var str=arr.join("*");
            console.log(str);
        //重构!
            function join(arr.separator){
                if(separator==undefined) separator=",";
                separator=String(separator);
                var str="";
                for(var i=0;i<arr.length;i++){
                    if(i!==arr.length-1) str+=arr[i]+separator;
                    else str+=arr[i];
                }
                return str;
            }

6、concat //连接数组 //数组连接若干个数组或者元素,返回一个新的连接完成的数组,与原数组无引用关系

            var arr=[1,2,3,4];
            arr.concat([5,6,7],[8,9]);
        //重构!
            function concat(arr){
                var arr1=[];
                for(var i=0;i<arr.length;i++){
                    arr1[i]=arr[i];
                }
                if(arguments.length===1) return arr1;
                for(var j=1;j<arguments.length;j++){
                    if(arguments[j]!==null && arguments[j].constructor===Array){
                        for(var k=0;k<arguments[j].length;k++){
                            arr1[arr1.length]=arguments[j][k];
                        }
                    }else{
                        arr1[arr1.length]=arguments[j];
                    }
                }
                return arr1;
            }
            var arr=[3,4,5];
            var arr1=concat(arr,"");
            console.log(arr1);

7、splice //将数组中从第几位(下标)开始删除的多少元素,并且返回被删除的元素组成的新数组 //将数组中从第几个位开始删除多少个元素后,并在该位置插入新的若干元素,返回删除元素组成的新数组 //在数组的第几位开始插入若干个元素,并且返回控的新数组

            var arr=[1,2,3,4]
            var arr1=arr.splice(1,2);//arr为[1,4],arr1为[2,3];
            var arr1=arr.splice(1);//删除到尾部
            var arr1=arr.splice(-1);//如果第一个参数是负数,则从后向前开始删除;(删除了一个)
            var arr1=arr.splice(0);//将一个数组的所有元素转移到另一个数组
            var arr1=arr.splice();//没有删除返回新数组
            var arr1=arr.splice(-3,2);//从倒数第3个元素向后删除2个元素

            var arr1=arr.splice(1,2,-2,-3);//从第1位开始向后删除两个元素,并且在该位置添加-2,-3,返回被删除两个元素组成的数组。
            var arr1=arr.splice(1,arr.length,0,-1,-2);//从第1个元素开始删除到数组尾部,并且添加0,-1,-2
            var arr1=arr.splice(1,0,0);//在第1位插入一个元素0,不删除,返回空数组
        //splice这个方法实现需要耗费大量时间
            var arr=[1,3,3,6,8,2,3,5,6,3,7,9,8,3,6,7,3,8,9];
            var len=arr.length;
            for(var i=0;i<len;){
                if(arr[i]===3) arr.splice(i,1);
                else i++;
            }
        //去重
            var arr=[1,3,3,6,8,2,3,5,6,3,7,9,8,3,6,7,3,8,9];
            var arr1=[];
            for(var i=0;i<arr.length;i++){
                var bool=false;
                for(var j=0;j<arr1.length;j++){
                    if(arr[i]===arr1[j]){
                        bool=true;
                        break;
                    }
                }
                if(!bool) arr1.push(arr[i]);
            }
            arr.length=0;
            for(var k=0;k<arr1.length;k++){
                arr[k]=arr1[k];
            }
            arr1.length=0;
            arr1=null;
            console.log(arr);

8、slice //从第几项开始到第几项结束复制这些元素到新数组中,原数组不变

            var arr=[1,2,3,4];
            var arr1=arr.slice();//复制原数组到新数组,没有引用关系
        //将列表转换为数组的3个方法,要记住!!
            var divs=document.getElementsByTagName("div");//获取body里所有的div
            第一种:    var arr=Array.prototype.slice.call(divs);
                        var arr=[].slice.call(divs);
            第二种:     var arr=Array.from(divs);//ES6
            第三种:    var arr=Array.prototype.concat.apply([],divs);
                        var arr=[].concat.apply([],divs);

            var arr1=arr.slice(2);//从第2(下标)开始复制
            var arr1=arr.slice(0);//复制数组
            var arr1=arr.slice();//复制数组
            var arr1=arr.slice(-2);//从后向前数第2个元素到尾部的所有元素复制
            var arr1=arr.slice(1,2);//从第一项复制到第二项,不包括结束这一项
        //重构!(有BUG)
            function slice(arr,start,end){
                if(start===undefined) start=0;
                if(end===undefined) end=arr.length;
                start=Number(start);
                end=Number(end);
                if(!isNaN(end) && isNaN(start)) start=0;
                if(isNaN(start)) return [];
                if(start<0) start=arr.length+start;
                if(end<0) end=arr.length+end;
                var arr1=[];
                for(var i=start;i<end;i++){
                    arr1[i-start]=arr[i];
                }
                return arr1;
            }

9、reverse //当前数组按照倒装顺序将原数组颠倒,并且返回原数组

            var arr=[2,3,4,5];
            var arr1=arr.reverse();
        //重构!方案1
            function reverse(arr){
                var len=parseInt(arr.length/2);
                for(var i=0;i<len;i++){
                    var temp=arr[i];
                    arr[i]=arr[arr.length-i-1];
                    arr[arr.length-i-1]=temp;
                }
                return arr;
            }
        //方案2
            function reverse(arr){
                var arr1=[];
                for(var i=0;i<arr.length;i++){
                    if(i in arr){
                        arr1[i]=arr[i];
                    }
                }
                arr.length=0;
                for(var j=arr1.length-1;j>=0;j--){
                    if(j in arr1){
                        arr[arr1.length-j-1]=arr1[j];
                    }
                }
                return arr;
            }

10、sort //排序 引用同一个地址

            var arr = [3, 7, 2, 9, 1, 0, 6, 5, 4, 4, 12, 11];
            var arr1=arr.sort();
            console.log(arr,arr1,arr==arr1);

            arr.sort(function(a,b){
                return a-b;
            });
            arr.sort(function(a,b){
                return b-a;
            });

            var arr=["a","c","b","d","e","ab","bc","def","aaa","efg"];
            arr.sort(function(a,b){
                return a.charCodeAt(0)-b.charCodeAt(0);
            });
    //对象型数组某个属性排序
            var arr=[
                {id:1001,name:"苹果IphoneX",price:6900,num:2,info:"最新的苹果手机"},
                {id:1002,name:"小米10",price:3900,num:3,info:"最新的小米手机"},
                {id:1003,name:"华为meta10",price:8900,num:4,info:"最新的华为手机"},
                {id:1004,name:"锤子手机",price:1900,num:1,info:"最新的锤子手机"},
                {id:1005,name:"三星手机",price:4900,num:2,info:"最新的三星手机"},
                {id:1006,name:"vivo手机",price:2900,num:4,info:"最新的vivo手机"},
                {id:1007,name:"魅族手机",price:1900,num:5,info:"最新的魅族手机"},
            ];
            arr.sort(function(a,b){
                return a.price-b.price;
            });
            console.log(arr);
        //排序算法
        //冒泡排序
            function sort(arr){
                var len=arr.length-1;
                while(len>0){
                    for(var i=0;i<arr.length-1;i++){
                        if(arr[i]>arr[i+1]){
                            var temp=arr[i];
                            arr[i]=arr[i+1];
                            arr[i+1]=temp;
                        }
                    }
                    len--;
                }
            }
        //选择排序
            function selectionSort(arr){
                var len=arr.length;
                var minIndex,temp;
                for(var i=0;i<len-1;i++){
                    minIndex=i;
                    for(var j=i+1;j<len;j++){
                        if(arr[j]<arr[minIndex]){
                            minIndex=j;//将最小数的索引保存
                        }
                    }
                    temp=arr[i];
                    arr[i]=arr[minIndex];
                    arr[minIndex]=temp;
                }
                return arr;
            }
        //快速排序
            function quickSort(arr){
                if(arr.length<=1){
                    return arr;
                }
                var pivotIndex=parseInt(arr.length/2);
                var pivot=arr.splice(pivotIndex,1)[0];
                var left=[];
                var right=[];
                for(var i=0;i<arr.length;i++){
                    if(arr[i]<pivot){
                        left.push(arr[i]);
                    } else{
                        right.push(arr[i]);
                    }
                }
                return quickSort(left).concat([pivot],quickSort(right));
            }

11、indexOf //在数组中查找元素,并且返回该元素的下标,如果没有找到返回-1

            var arr=[1,2,5,3,4,2,3,7,2,3,5];
            var index=arr.indexOf(5);//返回下标
            var index=arr.indexOf(3,4);//从下标为4开始查找

            var index=0;
            do{
                index=arr.indexOf(3,index);
                console.log(index);
            }while(++index>0);//找到为3的所有下标

            var arr=[1,3,3,6,8,2,3,5,6,3,7,9,8,3,6,7,3,8,9];
            var arr1=[]; 
            for(var i=0;i<arr.length;i++){
                if(arr1.indexOf(arr[i])<0) arr1.push(arr[i]);
            }
            console.log(arr1);//把没有重复的数找到
        //重构!
            function indexOf(arr,search,index){
                if(index===undefined) index=0;
                for(var i=index;i<arr.length;i++){
                    if(arr[i]===search) return i;
                }
                return -1;
            }

12、lastIndexOf //从后向前查找元素

            //lastIndexOf(要查找的元素,从什么位置开始查找);
                var arr=[1,3,3,6,8,2,3,5,6,3,7,9,8,3,6,7,3,8,9];
                var index=arr.lastIndexOf(3);
                console.log(index);

13、fill //填充

        //fill(要填充的值,从什么位置开始,到什么位置之前结束);
            var arr=[1,,,7];
            arr.fill(5,1,3);
            console.log(arr);
        //fill只能用于有长度的数组,如果不给开始位置和结束位置,就会把数组全部填充覆盖
        //用这种方式填充对象,就会造成填充同一个引用地址的对象

14、forEach //遍历数组,可以获取使用元素和下标,自动过滤空元素,空元素不遍历 //比for in来说,不会遍历到数组的属性 //比for来说,不会遍历到空元素 //有缺陷,函数中this指向会被改变

            arr.forEach(function(item,index,arr){
                console.log(item,index,arr);
                arr[index]=item+10;
            });
            console.log(arr);
        //桥接模式是设计模式的一种
        //桥接模式: 功能与实现分离,使用函数作为桥接方式,功能带入
            function forEach(arr,fn){
                for(var i=0;i<arr.length;i++){
                    if(i in arr) fn(arr[i],i,arr);
                }
            }
            var arr=[2,3,4,,7,5,8];
            forEach(arr,function(item,index,arr){
                console.log(item,index,arr);
            })
            forEach(arr,fn2);
            function fn2(item,index,arr){}

15、map //遍历数组,并且使用return返回元素,这些被返回的元素会被放在一个新数组中 //新数组的长度和原数组相同

            var arr=[1,2,5,,3,6,8];
            var arr1=arr.map(function(item,index,arr){
                return item+10;
            })
            console.log(arr1,arr);

            function map(arr,fn){
                var arr1=[];
                for(var i=0;i<arr.length;i++){
                    if(i in arr) arr1[i]=fn(arr[i],i,arr);
                }
                return arr1;
            }
            var arr=[1,2,5,,3,6,8];
            var arr1=map(arr,function(item){
                return item+10;
            });
            console.log(arr1);

            var arr=[1,3,3,6,8,2,3,5,6,3,7,9,8,3,6,7,3,8,9];
            for(var i=0;i<arr.length;i++){
                var index=i;
                while(index>-1){
                    index=arr.indexOf(arr[i],index+1);
                    if(index>-1)delete arr[i];//使用delete会变成松散型数组
                }
            }//不建议使用

            var arr1=arr.map(function(item){
                return item;
            });
            var arr1=[];
            arr.forEach(function(item){
                arr1.push(item);
            })
            console.log(arr1);

            var arr=[        {site:"网易",url:"http://www.163.com"},        {site:"腾讯",url:"http://www.qq.com"},        {site:"京东",url:"http://www.jd.com"},        {site:"淘宝",url:"http://www.taobao.com"},        {site:"天猫",url:"http://www.tmail.com"}        ]
            var str="";
            arr.forEach(function(item){
                str+="<a href='"+item.url+"'>"+item.site+"</a><br>";
            })
            document.body.innerHTML+=str;

            function sort(arr,fn){
                var len=arr.length-1;
                while(len>0){
                    for(var i=0;i<arr.length-1;i++){
                        //if(arr[i]>arr[i+1])
                        //if(arr[i]-arr[i+1]>0)
                        //if(a-b)
                        if(fn(arr[i],arr[i+1])>0){
                            var temp=arr[i];
                            arr[i]=arr[i+1];
                            arr[i+1]=temp;
                        }
                    }
                    len--;
                }
            }
            var arr = [3, 7, 2, 9, 1, 0, 6, 5, 4, 4, 12, 11];
            sort(arr,function(a,b){
                return b-a;
            });
            console.log(arr);

16、some //遍历数组,判断元素是否有满足条件的,如果有直接跳出返回true,否则返回false

            var arr=[1,4,6,5,8,3,2];
            var bool=arr.some(function(item,index,arr){
                return item>4
            });

            function some(arr,fn){
                for(var i=0;i<arr.length;i++){
                    if(i in arr && fn(arr[i],i,arr)) return true;
                }
                return false;
            }

17、every //遍历数组,并且判断每个元素是否满足条件,如果不满足直接跳出返回false,否则返回true

            var bool=arr.every(function(item,index,arr){
                return item>0;
            })
            console.log(bool);

            function every(arr,fn){
                for(var i=0;i<arr.length;i++){
                    if(i in arr && !fn(arr[i],i,arr)) return false;
                }
                return true;
            }
        //全选
            var all,list;
            init();
            function init(){
                list=document.getElementsByTagName("input");
                list=Array.from(list);
                all=list.splice(0,1)[0];
                all.onclick=clickHandler;
                list.forEach(function(item){
                    item.onclick=clickHandler;
                })
            }

            function clickHandler(){
                // console.log(this);//在点击事件中this是被点击的元素
                if(this===all){
                    list.forEach(function(item){
                        item.checked=all.checked;
                    })
                }else{
                    all.checked=list.every(function(item){
                        return item.checked;
                    })
                }
            }
        //随机乱序
            function getSecurityCode() {
            var arr = [];
            var i = 47;
            while (i++ < 122) {
            if (i > 57 && i < 65) continue;
            if (i > 90 && i < 97) continue;
            arr.push(String.fromCharCode(i));
            }
            arr.sort(function(){
                return Math.random()-0.5;
            });
            arr.length=4;
            return arr.join("");
        }

        console.log(getSecurityCode());
    //索引查找对象的问题
        var arr=[
        {id:1001,site:"网易",url:"http://www.163.com"},
        {id:1002,site:"腾讯",url:"http://www.qq.com"},
        {id:1003,site:"京东",url:"http://www.jd.com"},
        {id:1004,site:"淘宝",url:"http://www.taobao.com"},
        {id:1005,site:"天猫",url:"http://www.tmail.com"}
        ] 
        function searchObj(arr,obj){
        for(var i=0;i<arr.length;i++){
          if(arr[i].id===obj.id) return i;
        }
        return -1;
        } 
        //
        var arr=[
        {site:"网易",url:"http://www.163.com"},
        {site:"腾讯",url:"http://www.qq.com"},
        {site:"京东",url:"http://www.jd.com"},
        {site:"淘宝",url:"http://www.taobao.com"},
        {site:"天猫",url:"http://www.tmail.com"}
        ]
        function searchObj(arr,obj){
        for(var i=0;i<arr.length;i++){
          if(JSON.stringify(arr[i])===JSON.stringify(obj)) return i;
        }
        return -1;
        }
        var index=searchObj(arr,{site:"京东",url:"http://www.jd.com"});
        console.log(index);

18、filter //筛选过滤,就是讲满足条件的元素放在一个新数组中,并且返回这个新数组(存储是对象的都会改变其中的引用地址) //与map的区别就是返回数组的长度不一样

            var arr=[2,3,4,5,6,7,8]
            var arr1=arr.filter(function(item){
                return item>4;
            });
            console.log(arr1);

            var arr=[
            {id:1001,site:"网易",url:"http://www.163.com"},
            {id:1002,site:"腾讯",url:"http://www.qq.com"},
            {id:1003,site:"京东",url:"http://www.jd.com"},
            {id:1004,site:"淘宝",url:"http://www.taobao.com"},
            {id:1005,site:"天猫",url:"http://www.tmail.com"}
            ]
            var obj=arr.filter(function(item){
                return item.site==="京东"
            });
            obj.id=1008;
            console.log(arr);

19、reduce //归并 //如果没有初始值,value就是数组的第0位元素,而后面的item、则从下标为1开始遍历 //遍历的第二次运行时,value将会是上次运行return的返回值 //当数组的每个元素遍历完成后将最后一次的返回值返回到外面的变量

            var sum=arr.reduce(function(value,item,index,arr){
                return value+=item;
            })
            var max=arr.reduce(function(value,item){
                return value>item ? value : item;
            })
            console.log(sum);
        //当使用reduce设置最后的初始值时,value将会在开始为这个初始值
        //并且遍历将会从数组的第0项开始,item就是下标为0的元素开始
            var arr=[1,2,3,4,5,6,7];
            var sum=arr.reduce(function(value,item,index){
                console.log(value,item,index);
                return value+item;
            },100);

            var arr=[1,2,3,40,5,6,7];
            var obj=arr.reduce(function(value,item){
                if(value.max==undefined) value.max=item;
                if(value.min==undefined) value.min=item;
                if(value.max<item) value.max=item;
                if(value.min<item) value.min=item;
                return value;
            },{});
            console.log(obj);

            var arr=[
            {id:1001,site:"网易",url:"http://www.163.com"},
            {id:1002,site:"腾讯",url:"http://www.qq.com"},
            {id:1003,site:"京东",url:"http://www.jd.com"},
            {id:1004,site:"淘宝",url:"http://www.taobao.com"},
            {id:1005,site:"天猫",url:"http://www.tmail.com"}
            ]
            var obj=arr.reduce(function(value,item){
                if(item.site=="京东") value=item;
                return value;
            },null);
            console.log(obj);
        //重构!
            function reduce(arr,fn,initValue){
                var index=0;
                if(initValue===undefined){
                    initValue=arr[0];
                    index=1;
                }
                for(;index<arr.length;index++){
                    initValue=fn(initValue,arr[index],index,arr);
                }
                return initValue;
            }
            var arr=[1,2,3,4,5,6];
            var sum=reduce(arr,function(value,item,index){
                console.log(value,item,index);
                return value+item;
            });
            console.log(sum); 

20、扁平化数组 //flatMap

                var arr=[[1,2,3],[4,5,6,2],[7,6,9,1]];
                var arr1=arr.flatMap(function(item){
                    console.log(item);
                    return item;
                });
                console.log(arr1);
            //静态方法  static
                //Array.from();
                //Array.isArray();
            //实例方法
                //arr.filter();
                //arr.push();