1. 程式人生 > >js基礎--陣列方法

js基礎--陣列方法

  • join()

Array.join()方法將陣列中所有元素都轉化為字串並連線在一起,返回最後生成的字串。可以指定一個可選
的字串在生成的字串中來分隔陣列的各個元素。如果不指定分隔符,預設使用逗號。如以下程式碼所示:

var a=[1,2,3];//建立一個包含三個元素的陣列
a.join();//=>"1,2,3"
a.join("");//=>"1 2 3"
a.join("");//=>"123"
var b=new Array(10);//長度為10的空陣列
b.join('-')//=>'---------':9個連字號組成的字串

Array.join()方法是String.split()方法的逆向操作,後者是將字串分割成若干塊來建立一個數組。
  • reverse()

Array.reverse()方法將陣列中的元素顛倒順序,返回逆序的陣列。它採取了替換,換句
話說,它不通過重新排列的元素建立新的陣列,而是在原先的陣列中重新排列它們。例
如,下面的程式碼使用reverse()和join()方法生成字串“3, 2, 1” ;

var a = [1,2,3];
a. reverse(). join() //=〉” 3,2,1 ”,並且現在的a是[ 3,2,1]
  • sort()

Array.sort()方法將陣列中的元素排序並返回排序後的陣列。當不帶引數呼叫sort()時,陣列元素以字母表順序
排序(如有必要將臨時轉化為字串進行比較):

var a=new Array("banana","cherry","apple");
a.sort();
var s=a.join(",");//s=="apple,banana,cherry"

如果陣列包含undefined元素,它們會被排到陣列的尾部。

為了按照其他方式而非字母表順序進行陣列排序,必須給sort()方法傳遞一個比較函式。該函式決定了它的兩個
引數在排好序的陣列中的先後順序。假設第一個引數應該在前,比較函式應該返回一個小於0的數值。反之,假設
第一個引數應該在後,函式應該返回一個大於0的數值。並且,假設兩個值相等(也就是說,它們的順序無關緊
要),函式應該返回0。因此,例如,用數值大小而非字母表順序進行陣列排序,程式碼如下:

var a=[33,4,1111,222];
a.sort();//字母表順序:1111,222,33,4
a.sort(function(a,b){//數值順序:4,33,222,1111
return a-b;//根據順序,返回負數、0、正數
});
a.sort(function(a,b){return b-a});//數值大小相反的順序

注意,這裡使用匿名函式表示式非常方便。既然比較函式只使用一次,就沒必要給它們命名了。


另外一個數組元素排序的例子,也許需要對一個字串陣列執行不區分大小寫的字母表排序,比較函式首先將引數
都轉化為小寫字串(使用toLowercase()方法),再開始比較:

a = ['ant', 'Bug', 'cat', 'Dog']
a.sort(); //區分大小寫的排序: [’ Bug', 'Dog ’,’ant' ,cat']

a.sort(function(s,t) { //不區分大小寫的排序
var b = a.map(function(s) { return s.toLowerCase();})//不能直接使s.toLowerCase(),需要轉換
var c= a.map(function(t) { return t.toLowerCase();})
if (c < b) return -1;
if (c > b) return 1;
return 0;
});        
//=> ['ant ',’ Bug ',’cat ',’Dog']

 

  • concat()

Array.concat()方法建立井返回一個新陣列,它的元素包括呼叫concat()的原始陣列的元素和concat()的每
個引數。如果這些引數中的任何一個自身是陣列,則連線的是陣列的元素,而非陣列本身。但要注意,concat()
不會遞迴扁平化陣列的陣列。concat()也不會修改呼叫的陣列。下面有一些示例:

var a = [1,2,3];
a.concat(4, 5);返回//[ 1,2,3,4,5]
a.concat ([ 4, 5]);//返回[ 1,2,3,4,5]
a.concat([4,5], [6, 7]);//返回[1,2,3,4,5,6,7]
a.concat ( 4, [ 5, [ 6, 7]]);//返回[ 1,2,3,4,5,[6,7]],不會遞迴扁平化陣列的陣列
  • slice()


Array.slice()方法返回指定陣列的一個片段或子陣列。它的兩個引數分別指定了片段的開始和結束的位置。返回
的陣列包含第一個引數指定的位置和所有到但不含第二個引數指定的位置之間的所有陣列元素。如果只指定一個參
數,返回的陣列將包含從開始位置到陣列結尾的所有元素。如引數中出現負數,它表示相對於陣列中最後一個元素
的位置。例如,引數-1指定了最後一個元素,而-3指定了倒數第三個元素。注意,slice()不會修改呼叫的陣列。
下面有一些示例:

var a=[1,2,3,4,5];
a.slice(0,3);//返回[1,2,3]
a.slice(3);//返回[4,5]
a.slice(1,-1);//返回[2,3,4]
a.slice(-3,-2);//返回[3]

 

  • splice()

Array.splice()方法是在陣列中插入或刪除元素的通用方法。不同於slice()和concat(),splice()會修改調
用的陣列。注意,splice()和slice()擁有非常相似的名字,但它們的功能卻有本質的區別。

splice()能夠從陣列中刪除元素、插入元素到陣列中或者同時完成這兩種操作。在插入或刪除點之後的陣列元素
會根據需要增加或減小它們的索引值,因此陣列的其他部分仍然保持連續的。splice()的第一個引數指定了插入
和(或)刪除的起始位置。第二個引數指定了應該從陣列中刪除的元素的個數。如果省略第二個引數,從起始點開
始到陣列結尾的所有元素都將被刪除。splice()返回一個由刪除元素組成的陣列,或者如果沒有刪除元素就返回
一個空陣列。例如:

var a=[1,2,3,4,5,6,7,8];
a.splice(4);//返回[5,6,7,8];a是[1,2,3,4]
a.splice(1,2);//返回[2,3];a是[1,4]
a.splice(1,1);//返回[4];a是[1]

splice()的前兩個引數指定了需要刪除的陣列元素。緊隨其後的任意個數的引數指定了需要插入到陣列中的元
素,從第一個引數指定的位置開始插入。例如:

var a=[1,2,3,4,5];
a.splice(2,0,'a','b');//返回[];a是[1,2,'a','b',3,4,5]
a.splice(2,2,[1,2],3);//返回['a','b'];a是[1,2,[1,2],3,3,4,5]

注意,區別於concat(),splice()會插入陣列本身而非陣列的元素。
  • push ()和pop()

push()和pop()方法允許將陣列當做棧來使用。push()方法在陣列的尾部新增一個或多個元素,並返回陣列新的
長度。pop()方法則相反:它刪除陣列的最後一個元素,減小陣列長度並返回它刪除的值。注意,兩個方法都修改
並替換原始陣列而非生成一個修改版的新陣列。組合使用push()和pop()能夠用JavaScript陣列實現先進後出的
棧。例如:

var stack=[];//stack:[]
stack.push(1,2);//stack:[1,2] 返回2
stack.pop();//stack:[1] 返回2
stack.push(3);//stack:[1,3] 返回2
stack.pop();//stack:[1] 返回3
stack.push([4,5]);//stack:[1,[4,5]] 返回2
stack.pop()//stack:[1] 返回[4,5]
stack.pop();//stack:[] 返回1
  • unshift ()和shift()


unshift()和shift()方法的行為非常類似於push()和pop(),不一樣的是前者是在陣列的頭部而非尾部進行元素的插入和刪除操作。
unshift()在陣列的頭部新增一個或多個元素,並將已存在的元素移動到更高索引的位置來獲得足夠的空間,最後返回陣列新的長度。
shift()刪除陣列的第一個元素並將其返回,然後把所有隨後的元素下移一個位置來填補陣列頭部的空缺。例如:

var a=[];//a:[]
a.unshift(1);//a:[1]返回:1
a.unshift(22);//a:[22,1]返回:2
a.shift();//a:[1]返回:22
a.unshift(3,[4,5]);//a:[3,[4,5],1]返回:3
a.shift();//a:[[4,5],1]返回:3
a.shift();//a:[1]返回:[4,5]
a.shift();//a:[]返回:1

注意,當使用多個引數呼叫unshift()時。引數是一次性插入的(就像splice()方法)而非一次一個地插入。這
意味著最終的陣列中插入的元素的順序和它們在引數列表中的順序一致。而假如元素是一次一個地插入,它們的順序應該是反過來的。
  • toString ()和tolocaleString()

陣列和其他JavaScript物件一樣擁有toString()方法。針對陣列,該方法將其每個元素轉化為字串(如有必要
將呼叫元素的toString()方法)\並且輸出用逗號分隔的字串列表。注意,輸出不包括方括號或其他任何形式的
包裹陣列值的分隔符。例如:

[1,2,3].toString()//生成'1,2,3'
["a","b","c"].toString()//生成'a,b,c'
[1,[2,'c']].toString()//生成'1,2,c'

注意,這裡與不使用任何引數呼叫join()方法返回的字串是一樣的。
toLocaleString()是toString()方法的本地化版本。它呼叫元素的toLocaleString()方法將每個陣列元素轉化
為字串,並且使用本地化(和自定義實現的)分隔符將這些字串連線起來生成最終的字串。

 

ECMAScript 5中的陣列方法

ECMAScript 5定義了9個新的陣列方法來遍歷、對映、過濾、檢測、簡化和搜尋陣列。

      首先,大多數方法的第一個引數接收一個函式,並且對陣列的每個元素(或一些元素)呼叫一次該函式。如果是稀疏陣列,對不存在的元素不呼叫傳遞的函式。在大多數情況下,呼叫提供的函式使用三個引數:陣列元素、元素的索引和陣列本身。通常,只需要第一個引數值,可以忽略後兩個引數。大多數ECMAScript 5陣列方法的第一個引數是一個函式,第二個引數是可選的。如果有第二個引數,則呼叫的函式被看做是第二個引數的方法。也就是說,在呼叫函式時傳遞進去的第二個引數作為它的this關鍵字的值來使用。被呼叫的函式的返回值非常重要,但是不同的方法處理返回值的方式也不一樣。ECMAScript 5中的陣列方法都不會修改它們呼叫的原始陣列。當然,傳遞給這些方法的函式是可以修改這些陣列的。

  • forEach()

forEach()方法從頭至尾遍歷陣列,為每個元素呼叫指定的函式。如上所述,傳遞的函式作為forEach()的第一個
引數。然後forEach()使用三個引數呼叫該函式:陣列元素、元素的索引和陣列本身。如果只關心陣列元素的值,
可以編寫只有一個引數的函式——額外的引數將忽略:

var data=[1,2,3,4,5];//要求和的陣列
//計算陣列元素的和值
var sum=0;//初始為0
data.forEach(function(value){sum+=value;});//將每個值累加到sum上
sum//=>15//每個陣列元素的值自加1
data.forEach(function(v,i,a){a[i]=v+1;});
data//=>[2,3,4,5,6]

注意,forEach()無法在所有元素都傳遞給呼叫的函式之前終止遍歷。也就是說,沒有像for迴圈中使用的相應的
break語句。如果要提前終止,必須把forEach()方法放在一個try塊中,並能丟擲一個異常。如果forEach()調
用的函式丟擲foreach.break異常,迴圈會提前終止:

function foreach(a,f,t){
    try{a.forEach(f,t);}
    catch(e){
        if(e===foreach.break)return;
        else throw e;
    }
}
foreach.break=new Error("StopIteration");
  • map()

map()方法將呼叫的陣列的每個元素傳遞給指定的函式,並返回一個數組,它包含該函式的返回值。例如:

a=[1,2,3];
b=a.map(function(x){return x*x;});//b是[1,4,9]

傳遞給map()的函式的呼叫方式和傳遞給forEach()的函式的呼叫方式一樣。但傳遞給map()的函式應該有返回
值。注意,map()返回的是新陣列:它不修改呼叫的陣列。如果是稀疏陣列,返回的也是相同方式的稀疏陣列:它
具有相同的長度,相同的缺失元素。
  • filter()

fliter()方法返回的陣列元素是呼叫的陣列的一個子集。傳遞的函式是用來邏輯判定的:該函式返回true或
false。呼叫判定函式就像呼叫forEach()和map()一樣。如果返回值為true或能轉化為true的值,那麼傳遞給判
定函式的元素就是這個子集的成員,它將被新增到一個作為返回值的陣列中。例如:

a=[5,4,3,2,1];
smallvalues=a.filter(function(x){return x<3});//[2,1]
everyother=a.filter(function(x,i){return i%2==0});//[5,3,1]

注意,filter()會跳過稀疏陣列中缺少的元素,它的返回陣列總是稠密的。為了壓縮稀疏陣列的空缺,程式碼如下:

var dense=sparse.filter(function(){return true;});

甚至,壓縮空缺並刪除undefined和null元素,可以這樣使用filter():

a=a.filter(function(x){return x!==undefined&&x!=null;});
  • every()和some()

every()和some()方法是陣列的邏輯判定:它們對陣列元素應用指定的函式進行判定,返回true或false。

every()方法就像數學中的“針對所有”的量詞:當且僅當針對陣列中的所有元素呼叫判定函式都返回true,它才返
回true:

a=[1,2,3,4,5];
a.every(function(x){return x<10;})//=>true:所有的值<10
a.every(function(x){return x%2===0;})//=>false:不是所有的值都是偶數

some()方法就像數學中的“存在”的量詞:當陣列中至少有一個元素呼叫判定函式返回true,它就返回true;並且
當且僅當數值中的所有元素呼叫判定函式都返回false,它才返回false:

a=[1,2,3,4,5];
a.some(function(x){return x%2===0;})//=>true:a含有偶數值
a.some(isNaN)//=>false:a不包含非數值元素

注意,一旦every()和some()確認該返回什麼值它們就會停止遍歷陣列元素。some()在判定函式第一次返回true
後就返回true,但如果判定函式一直返回false,它將會遍歷整個陣列。every()恰好相反:它在判定函式第一次
返回false後就返回false,但如果判定函式一直返回true,它將會遍歷整個陣列。注意,根據數學上的慣例,在
空陣列上呼叫時,every()返回true,some()返回false。
  • reduce()和reduceRight()

reduce()和reduceRight()方法使用指定的函式將陣列元素進行組合,生成單個值。這在函數語言程式設計中是常見
的操作,也可以稱為“注入”和“摺疊”。舉例說明它是如何工作的:

var a=[1,2,3,4,5]
var sum=a.reduce(function(x,y){return x+y},0);//陣列求和
var product=a.reduce(function(x,y){return x*y},1);//陣列求積
var max=a.reduce(function(x,y){return(x>y)?x:y;});//求最大值

reduce()需要兩個引數。第一個是執行化簡操作的函式。化簡函式的任務就是用某種方法把兩個值組合或化簡
為一個值,並返回化簡後的值。在上述例子中,函式通過加法、乘法或取最大值的方法組合兩個值。第二個
(可選)的引數是一個傳遞給函式的初始值。

reduce()使用的函式與forEach()和map()使用的函式不同。比較熟悉的是,陣列元素、元素的索引和陣列本
身將作為第2~4個引數傳遞給函式。第一個引數是到目前為止的化簡操作累積的結果。第一次呼叫函式時,第
一個引數是一個初始值,它就是傳遞給reduce()的第二個引數。在接下來的呼叫中,這個值就是上一次化簡函
數的返回值。在上面的第一個例子中,第一次呼叫化簡函式時的引數是0和1。將兩者相加並返回1。再次呼叫時
的引數是1和2,它返回3。然後它計算3+3=6、6+4=10,最後計算10+5=15。最後的值是15,reduce()返回這
個值。

可能已經注意到了,上面第三次呼叫reduce()時只有一個引數:沒有指定初始值。當不指定初始值呼叫
reduce()時,它將使用陣列的第一個元素作為其初始值。這意味著第一次呼叫化簡函式就使用了第一個和第二
個數組元素作為其第一個和第二個引數。在上面求和與求積的例子中,可以省略初始值引數。

在空陣列上,不帶初始值引數呼叫reduce()將導致型別錯誤異常。如果呼叫它的時候只有一個值——陣列只有一
個元素並且沒有指定初始值,或者有一個空陣列並且指定一個初始值——reduce()只是簡單地返回那個值而不會
呼叫化簡函式。

reduceRight()的工作原理和reduce()一樣,不同的是它按照陣列索引從高到低(從右到左)處理陣列,而不
是從低到高。如果化簡操作的優先順序是從右到左,你可能想使用它,例如:

var a=[2,3,4]//計算2^(3^4)。乘方操作的優先順序是從右到左
var big=a.reduceRight(function(accumulator,value){
    return Math.pow(value,accumulator);
});


注意,reduce()和reduceRight()都能接收一個可選的引數,它指定了化簡函式呼叫時的this關鍵字的值。可
選的初始值引數仍然需要佔一個位置。如果想讓化簡函式作為一個特殊物件的方法呼叫,請參看
Function.bind()方法。

值得注意的是,上面描述的every()和some()方法是一種型別的陣列化簡操作。但是不同的是,它們會盡早終
止遍歷而不總是訪問每一個數組元素。

為了簡單起見,到目前位置所展示的例子都是數值的,但數學計算不是reduce()和reduceRight()的唯一意
圖。它計算兩個物件的“並集”,並返回另一個新物件,新物件具有二者的屬性。該函式期待兩個物件並返回另
一個物件,所以它的工作原理和一個化簡函式一樣,並且可以使用reduce()來把它一般化,計算任意數目的對
象的“並集”。

var objects=[{x:1},{y:2},{z:3}];
var merged=objects.reduce(union);//=>{x:1,y:2,z:3}

回想一下,當兩個物件擁有同名的屬性時,union()函式使用第一個引數的屬性值。這樣,reduce()和
reduceRight()在使用union()時給出了不同的結果:

var objects=[{x:1,a:1},{y:2,a:2},{z:3,a:3}];
var leftunion=objects.reduce(union);//{x:1,y:2,z:3,a:1}
var rightunion=objects.reduceRight(union);//{x:1,y:2,z:3,a:3}
  • indexOf()和lastIndexOf()

indexOf()和lastIndexOf()搜尋整個陣列中具有給定值的元素,返回找到的第一個元素的索引或者如果沒有找到
就返回-1。indexOf()從頭至尾搜尋,而lastIndexOf()則反向搜尋。

a=[0,1,2,1,0];
a.indexOf(1)//=>1:a[1]是1
a.lastIndexOf(1)//=>3:a[3]是1
a.indexOf(3)//=>-1:沒有值為3的元素

不同於本節描述的其他方法,indexOf()和lastIndexOf()方法不接收一個函式作為其引數。第一個引數是需要搜
索的值,第二個引數是可選的:它指定陣列中的一個索引,從那裡開始搜尋。如果省略該引數,indexOf()從頭開
始搜尋,而lastIndexOf()從末尾開始搜尋。第二個引數也可以是負數,它代表相對陣列末尾的偏移量,對於
splice()方法:例如,-1指定陣列的最後一個元素。

如下函式在一個數組中搜索指定的值並返回包含所有匹配的陣列索引的一個數組。它展示瞭如何運用indexOf()的
第二個引數來查詢除了第一個以外匹配的值。

//在陣列中查詢所有出現的x,並返回一個包含匹配索引的陣列
function findall(a,x){
    var results=[],//將會返回的陣列
        len=a.length,//待搜尋陣列的長度
        pos=0;//開始搜尋的位置
    while(pos<len){//迴圈搜尋多個元素...
        pos=a.indexOf(x,pos);//搜尋
        if(pos===-1)break;//未找到,就完成搜尋
        results.push(pos);//否則,在陣列中儲存索引
        pos=pos+1;//並從下一個位置開始搜尋
    }
    return results;//返回包含索引的陣列
}

注意,字串也有indexOf()和lastIndexOf()方法,它們和陣列方法的功能類似。