內置對象Array及Array常見操做

Array內置對象的屬性

數組方法:

sort(): arrayObject.sort(sortby);前端

sortby可選,規定排序順序,可是必須是函數。sort() 方法用於對數組的元素進行排序。數組

若是調用該方法時沒有使用參數,將按字母順序對數組中的元素進行排序,說得更精確點,是按照字符編碼的順序進行排序,A在a以前。瀏覽器

要實現這一點,首先應把數組的元素都轉換成字符串(若有必要),以便進行比較。服務器

實際生產中,受限於服務器成本等因素,當單次數據查詢成爲總體性能瓶頸時,也會考慮經過將排序在前端完成的方式來優化性能。dom

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表明倒數第二個元素,以此類推。ui

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]‘; }

常見的數組問題: 

一、數組高效去重

原理:新建一新數組,遍歷傳入數組,值不在新數組就加入該新數組中;

注意點:判斷值是否在數組的方法「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)]

二、數組順序擾亂 

原理:每次從元數組中抽取一個,而後添加到新數組中,並在原數組中刪除。

注意點: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就會改變原來的數組。

三、數組求交集

原理:利用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
});

四、數組求並集

原理:鏈接連個數組並去重

注意: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]);

五、數組去重的實現

一、基本數組去重

原理:新建一個數組並返回,把原數組的元素在新建數組中沒有存在的添加到新數組中。

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

二、利用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;
}

三、先排序後去重

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());

六、快速排序的實現

方法一(儘量不用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的平方,另外快速排序是不穩定的。

七、生成一個二維或者多維的數組,使用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]);

八、對數組進行循環的時候,若是不知道須要循環幾回就把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);
相關文章
相關標籤/搜索