内置对象Array及Array常见操作

Array内置对象的属性

数组方法:

sort(): arrayObject.sort(sortby);

sortby可选,规定排序顺序,但是必须是函数。sort() 方法用于对数组的元素进行排序。

如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,说得更精确点,是按照字符编码的顺序进行排序,A在a之前。

要实现这一点,首先应把数组的元素都转换成字符串(如有必要),以便进行比较。

实际生产中,受限于服务器成本等因素,当单次数据查询成为整体性能瓶颈时,也会考虑通过将排序在前端完成的方式来优化性能。

function sortBy(a,b)
{
    return a - b ;// 正序
}

reverse():arrayObject.reverse()方法用于颠倒数组中元素的顺序。arrayObject.reverse(),该方法会改变原来的数组,而不会创建新的数组。

var arrs = [1,2,3,4];
console.log(arrs.reverse()); //[4,3,2,1]

splice(): splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目组成的数组,该方法会改变原始数组

arrayObject.splice(index,howmany,item1,.....,itemX);

//实例如下

var arr = new Array(6)
arr[0] = "George"
arr[1] = "John"
arr[2] = "Thomas"
arr[3] = "James"
arr[4] = "Adrew"
arr[5] = "Martin"

var del = arr.splice(2,3,"William")
del    //["Thomas", "James", "Adrew"]
arr    //["George", "John", "William", "Martin"]

toString(): 将数组转换为一个字符串,并且返回这个字符串;这个字符串默认以","进行分割。

var arrs = [1,2];
console.log(arrs.toString()); // 1,2

slice(): arrs.slice(start,end);从数组中截取一段,并返回。

start参数【必须】从何处开始选取(包括start),如果是负数,那么会从尾部选取,比如-1代表最后一个元素,-2代表倒数第二个元素,以此类推。

End参数【可选】规定是从何处结束选取(不包括end),如果没有指定该参数,那么数组会包含从start开始到数组结束的所有元素,如果该参数是负数的话,那么它规定的是从数组尾部开始算起的元素。

reduce(),归并方法:前向归并与

reduceRight(),后项归并

这两个的主要区别是从哪头开始遍历,迭代次数为ar.length - 1

var values = [1,2,3,4,5,6];
var i = 1;
var sum = values.reduce(function(prev,cur,index,array){
    console.log("prev  " + parseInt(prev));
    console.log("cur   " + parseInt(cur));
    console.log("迭代次数   " + i++)
    return prev + cur;
});
console.log(sum);

 //输出结果
prev  1
cur   2
迭代次数   1
prev  3
cur   3
迭代次数   2
prev  6
cur   4
迭代次数   3
prev  10
cur   5
迭代次数   4
prev  15
cur   6
迭代次数   5
21
var values = [1,2,3,4,5,6];
var i = 1;
var sum = values.reduceRight(function(prev,cur,index,array){
    console.log("prev  " + parseInt(prev));
    console.log("cur   " + parseInt(cur));
    console.log("迭代次数   " + i++)
    return prev + cur;
});
console.log(sum);

//输出结果
//
prev  6
cur   5
迭代次数   1
prev  11
cur   4
迭代次数   2
prev  15
cur   3
迭代次数   3
prev  18
cur   2
迭代次数   4
prev  20
cur   1
迭代次数   5
21

数组判断:

使用typeof不能测出来,因为数组是返回"object"的。 

//方法1 自带的isArray方法,需要考虑IE8-
var array6 = [];
Array.isArray(array6 );//true

//方法2 利用instanceof运算符,某些IE版本不兼容
var array5 = [];
array5 instanceof Array;//true

//方法3 能力检测,测试是否具有数组的一些方法,如slice();
array.slice
//方法4 利用toString的返回值,最好的方法 function isArray(o) { return Object.prototype.toString.call(o) === ‘[object Array]‘; }

常见的数组问题: 

1、数组高效去重

原理:新建一新数组,遍历传入数组,值不在新数组就加入该新数组中;

注意点:判断值是否在数组的方法“indexOf”是ECMAScript5 方法,IE8以下不支持,需多写一些兼容低版本浏览器代码。

// 最简单数组去重法1
function unique(array){
  var n = []; //一个新的临时数组
  //遍历当前数组
  for(var i = 0; i < array.length; i++){
    //如果当前数组的第i已经保存进了临时数组,那么跳过,
    //否则把当前项push到临时数组里面
    if (n.indexOf(array[i]) == -1) n.push(array[i]);
  }
  return n;
}

// 借助于Set对象与...方法
[...new Set(arr)]

2、数组顺序扰乱 

原理:每次从元数组中抽取一个,然后添加到新数组中,并在原数组中删除。

注意点:arrayObject.splice(index,howmany,item1,.....,itemX) : splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目(这里是一个数组)。该方法会改变原始数组。item是向数组中添加的新元素。

delete删除可以对数组和对象进行元素的删除,数组删除之后,使用Undefined来填补。对象就是删除属性的值(没有了)。

//每次随机抽一个数并移动到新数组中
function shuffle(array) {
    var copy = [],
        n = array.length,
        i;
    // 如果还剩有元素则继续。。。
    while (n) {
        // 随机抽取一个元素
        i = Math.floor(Math.random() * array.length);
        // 如果这个元素之前没有被选中过。。
        if (i in array) {
            copy.push(array[i]);
            delete array[i];
            n--;
        }
    }
    console.log(array);
    console.log(copy);
    return copy;
}
shuffle([2,5,6,9,8,5]);

这样本来的数组也被改变了,变为空。如果在进入函数的时候把array赋值给另一个变量也是不可行的,因为数组的访问也是按引用的,除非深度复制一份副本(for循环)。不然使用delete||splice就会改变原来的数组。

3、数组求交集

原理:利用filter()方法,返回满足条件的值组成的数组。

相同使用方法的方法如下:

  every():每项都(满足要求)为真则为真。

  filter():返回为真的项组成的数组。

  forEach():每一项都执行给定函数的操作,没有返回值。

  map():执行函数操作,返回操作的返回值组成的数组。

  some():任意项为真则为真。

以下是公用的模版形式:

var result = ArrObj.func(function(item,index,ArrObj){
  return (item >2);//条件
});
//利用filter和数组自带的indexOf方法
array1.filter(function(n) {
     return array2.indexOf(n) != -1
});

4、数组求并集

原理:连接连个数组并去重

注意:concat():concat() 方法用于连接两个或多个数组。该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。arrayObject.concat(arrayX,arrayX,......,arrayX)

function unique(arr1,arr2){
    var a = arr1.concat(arr2),result = [];
    for (var i = 0,len = a.length;i<len;i++){
        if(result.indexOf(a[i]) == -1){
            result.push(a[i]);
        }        
    }
    return result;
}
unique([2,5,6,5,6,8],[5,8,9,2]);

5、数组去重的实现

1、基本数组去重

原理:新建一个数组并返回,把原数组的元素在新建数组中没有存在的添加到新数组中。

Array.prototype.unique = function(){
    var result = [];
    this.forEach(function(v){
        if(result.indexOf(v) < 0){
            result.push(v);
        }
    });
    return result;
}

2、利用hash表去重,这是一种空间换时间的方法,这里如果存在元素是引用类型的就会出问题的

原理:借助于一个对象来进行判断是否唯一

Array.prototype.unique = function(){
    var result = [],hash = {};
    this.forEach(function(v){
        if(!hash[v]){
            hash[v] = true;
            result.push(v);
        }
    });
    return result;
}

上面的方法存在一个bug,对于数组[1,2,'1','2',3],去重结果为[1,2,3],原因在于对象对属性索引时会进行强制类型转换,arr[‘1’]和arr[1]得到的都是arr[1]的值,因此需做一些改变:

Array.prototype.unique = function(){
    var result = [],hash = {};
    this.forEach(function(v){
        var type = typeof(v);  //获取元素类型
        hash[v] || (hash[v] = new Array());
        if(hash[v].indexOf(type) < 0){
            hash[v].push(type);  //存储类型
            result.push(v);
        }
    });
    return result;
}

3、先排序后去重

Array.prototype.unique = function(){
    this.sort();
    var result = this;
    result.forEach(function(v,i){
        if(v === result[i+1]){
            result.splice(i,1);
        }
    });
    return result;
}

[1,2,5,6,4,"1",2].unique();

function randomArr(num,min,max){
    var result = [];
    while(num--){
        result.push(Math.floor(Math.random()*(max-min)) + min +1);
    }
    return result;
}

var arr = randomArr(20000,1,20000);

console.log(arr.unique());

6、快速排序的实现

方法一(尽可能不用js数组方法):

function quickSort(arr){
    qSort(arr,0,arr.length - 1);
}
function qSort(arr,low,high){
    if(low < high){
        var partKey = partition(arr,low,high);
        qSort(arr,low, partKey - 1);
        qSort(arr,partKey + 1,high);
    }
}
function partition(arr,low,high){
    var key = arr[low];  //使用第一个元素作为分类依据
    while(low < high){
        while(low < high && arr[high] >= arr[key])
            high--;
        arr[low] = arr[high];
        while(low < high && arr[low] <= arr[key])
            low++;
        arr[high] = arr[low];
    }
    arr[low] = key;
    return low;
}

方法二(使用js数组方法):

function quickSort(arr){
   if(arr.length <= 1) return arr;
   var index = Math.floor(arr.length/2);
   var key = arr.splice(index,1)[0];
   var left = [],right = [];
   arr.forEach(function(v){
       v <= key ? left.push(v) : right.push(v);
   });
   return quickSort(left).concat([key],quickSort(right));
}

另外要知道,快速排序的平均时间复杂度O(nlogn),最坏情况是有序的情况,时间复杂度为n的平方,另外快速排序是不稳定的。

7、生成一个二维或者多维的数组,使用for循环来赋值 

function to2Arr(x,y,r){
    var resArr = new Array(y);
    var sArr = new Array(x);
    for (var i = 0; i < x; i++){
        sArr[i] = r;
    }
    for (var j = 0; j < y; j++){
        resArr[j] = sArr;
    }

    console.log(resArr);
    return resArr;
}
to2Arr(5,5,1);//行数、列数、初始值 

如下的三维数组:

function to3Arr(x,y,z,r){
    var resArr = new Array(y);
    var sArr = new Array(x);
    var res3deg = new Array(z);
    for (var i = 0; i < x; i++){
        sArr[i] = r;
    }
    for (var j = 0; j < y; j++){
        resArr[j] = sArr;
    }
    for(var k = 0;k < z; k++){
        res3deg[k] = resArr;
    }
    console.log(resArr);
    console.log(res3deg);
    return res3deg;
}
to3Arr(5,5,5,1);

如下生成一个数组乘积的二维数组:

function fn(n,arr){
    var arr2deg = new Array();
    for(var i=0;i<n;i++){
        arr2deg[i] = new Array();
        for(var j=0;j<n;j++){            
            arr2deg[i][j] = arr[i]*arr[j];
        }
    }
    return arr2deg;
}
fn(4,[1,2,3,4]);

8、对数组进行循环的时候,如果不知道需要循环几次就把for方法放在一个函数中,然后使用for来调用

如下这般:

function func(n,arr,m,maxlen){
    var res = arr;
    for(var i=0;i<m;i++){
        _do(res,maxlen);
    }

    function _do(arrCur,maxlen){
        for(var j=0;j<n;j++){
            for(var k=0,len=arrCur.length;k<len;k++){
                if(k-j<=maxlen && j-k<=maxlen){
                    res.push(arr[j]*arrCur[k]);
                }
            }
        }
        console.log(res);
        res = res.slice(len);
        console.log(res)
    }

    function getMax(arrays){ //获取数组最大值
        return arrays.reduce(function(pre,cur,index,array){  
            return Math.max(pre,cur);  
        });  
    } 

    return getMax(res);

}

func(7,[2,3,40,5,6,-8,9],3,4);

转载于:https://www.cnblogs.com/changyangzhe/p/5726987.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值