第 8 章  Array

德嘉書業 / 德嘉資訊科技 (www.takka.com.hk) 作者: 伍新華 Email: ng-sun-wah@graduate.hku.hk

8.1 網頁中預設物件的陣列

8.2 自訂陣列

8.3 Array 的 length

8.4 Array 的 methods

1. arrayName.concat( )

2. arrayName.join( )

3. arrayName.pop( )

4. arrayName.push( )

5. arrayName.reverse( )

6. arrayName.shift( )

7. arrayName.slice( )

8. arrayName.splice( )

9. arrayName.sort( )

10. arrayName.toString( )

11. arrayName.unshift( )


 

  Array 中文譯作陣列, 是指一列, 或多欄和多列, 順序排列的的名單, 而我們可以利用陣列名稱及排序號數來叫用這陣列中的成員 (element)。

  若是單維陣列 (one dimensional array), 就是一列順序的名單, 若是二維陣列 (two dimensional array), 就是列與欄所組成的順序名單, 例如:

成員[0,0] 成員[0,1] 成員[0,2]
成員[1,0] 成員[1,1] 成員[1,2]
成員[2,0] 成員[2,1] 成員[2,2]
成員[3,0] 成員[3,1] 成員[3,2]

  本書的例子只用到單維陣列。

  另請留意陣列的排序是從 0 開始, 例如 0 1 2 3 . . . , 不是 1 2 3 4 . . . 。

 

 

8.1 網頁中預設物件的陣列

  當我們在網頁中放下一些預設物件, 這些物件自動各組成一個排序 (這就是陣列), 例如以下的網頁:

 

 

  這網頁四幅圖片會自動形成一個 array, 是為 document.images[i], 這處的 [i] 是index (序號), [i] 的排序是從 0 開始, 所以有以下排列:

第一幅圖片:   document.images[0]
第二幅圖片:   document.images[1]
第三幅圖片:   document.images[2]
第四幅圖片:   document.images[3]

 

  上圖的例子還有三個 links (連結) 的陣列: document.links[0]document.links[1] document.links[2]

 

  在一般網頁, 我們可能會用到以下物件的陣列, 在一個陣列中, 各成員的排序是依據在網頁原始檔案中各標籤 (tag) 的位置排序:

document.anchors[i] <a> (書籤) 的排序
document.embeds[i] <embed> 的排序
document.forms[i] <form> 的排序
document.images[i] <img> (圖片) 的排序
document.links[i] <a href=" "> (連結) 的排序
function.arguments[i] 一個 function 內的引數排序
form.elements[i] 一個 form 內各元件 (text、radio 等) 的排序
select.options[i] 一個選擇項目內的 <options> 的排序
window.frames[i] 一個 window 內的 <frame> (窗格) 的排序
window.history[i] 一個視窗內的 history 項目記錄排序
select.options[i] 一個選擇項目內的 <options> 的排序

       

 

練習-57 預設物件的 array

  首先讓我們看一個 <img> (圖片) 及 <form> 的例子, 以下網頁有兩幅圖示及三個 <form>, 你可看看如何使用 array 來叫用某一幅圖示或某個 <form> 內某項元件。留意排序是由 0 開始, 例如 0 1 2 3 ..., 不是 1 2 3 4 ...。

1. 請用瀏覽器開啟示範磁碟中的 array1.htm, 這檔案有以下內容:

<html> <body>

<img src=void width=
150 height=150 alt="第一幅圖片">
<img src=void width=
150 height=150 alt="第二幅圖片" >

<form name=
fm1>
<input type=text name=
tx1 value="Good morning" size=20>
<input type=text name=
tx2 value="Good afternoon" size=20>
<input type=button name=
bn1 value="看第一幅圖片 "
  onClick="document.images[
0].src='cat.jpg ' ">
</form>

<form name=fm2>
<input type=button name=
bn2 value="看第二幅圖片 "
  onClick="document.images[
1].src='chim.jpg' ">
</form>

<form>
<input type=button value="
按鈕用英文顯示 "
onClick="document.forms[
0].elements[2].value='View the 1st picture';
document.forms[
1].elements[0].value='View the 2nd picture' ">
</form>

</body> </html>

2. 請你試試三個按鈕的反應

 

1. 首先看這兩個圖片:

<img src=void width=150 height=150 alt="第一幅圖片 ">
<img src=void width=
150 height=150 alt="第二幅圖片 " >

  這兩個圖片排序上是 document.images[0] document.images [1], 我們可以使用這兩個名稱來指定這兩幅圖片, 例如:

document.images[0].src='cat.jpg'

  這是將 cat.jpg 作為 document.images[0] 的圖片來源 (src)。請同時參看 練習-65 的例子, 該處是直接使用圖片的位置名稱, 這處則使用排序編號。

2. <form> 的排序是另一個 array, 例如第一個 <form>document.forms[0], 這 form 內的 <input> 元件是 elements[i], 請看這例子:

 

  留意這處的按鈕是第一個 <form> (即是 forms[0] ) 內第三個元件 (即是 element[2] )。

 

3. 在網頁下方的按鈕, 在 onClick 時有以下兩個設定:

document.forms[0].elements[2].value='View the 1st picture'

  這是將 forms[0] 內的第三個元件 (elements[2] ) 上的文字變為 'View the 1st picture'

 

4. 在實際編寫網頁時, 我們多數會直接使用元件的名稱, 例如

document.fm1.bn.value='View the 1st picture'

  這方法較為方便。

 

 


8.2 自訂陣列

  前一節說的陣列物件是瀏覽器中預設的物件, 我們也可以自訂一個陣列, 然後用排序號數來叫用這陣列的成員。自訂陣列是使用 new Array( ) 這語法, 例如:

 

 

  若 array 內的成員是文字, 就要放在 " " 內, 若是數字或變數, 就不需要, 例如: colors=new Array(1, 3, 5, "black", "blue" )

  要指定 array 內某一個成員, 可以使用陣列編號, 例如 colors[1] 是 blue, colors[5] 是 gold, 我們也可直接使用成員的名稱, 例如 colors["blue"]colors["gold"] 等等。

  以下例子是另一個設定 array 的方法, 請你造出這檔案, 看有什麼結果:

<html> <body>
<script>
colors = new Array( )
colors[0] = "black"
colors[1] = "blue"
colors[2] = "brown"
colors[4] = "cyan"

for ( i=
0; i <= 4; i++ ) { document.write( colors [i] + "<br>") }
</script>
</body> </html>

 

  在這例子, 筆者故意漏空 colors[3] , 在這一項你會見到 undefined 這名稱, 表示未有定義, 用這方式, 你可保留一個位置, 日後才使用。若用前一個方法來設定, 可直接在該位置放下 undefined 這字, 例如:

colors =new Array("black", "blue", "brown", "undefined", "cyan")

 

  若 array 內的成員全部是文字 (是為 array literals), 沒有數字或變數, 可用方括號 [ ] 來設定: colors=["black", "blue", "brown", "cyan" ]

  使用這方式, 可隨時漏空一個, 例如:

 

  自訂陣列常用於遊戲的程式, 以下例子是一個測驗遊戲, 筆者將 5 幅圖片檔案名稱排成一個陣列 (在實際的遊戲中, 這可能有數十個圖片檔案名稱), 用者按一個按鈕, 就會顯示某一個序號的動物圖片, 同時有文字框讓觀看者輸入這動物的名稱, 再按這按鈕就顯示下一個序號的圖片, 直至最尾就由頭重複再顯示。

  此外, 這網頁中還有另一個名為 [提示] 的按鈕, 按一下就會在另一個文字框顯示該動物名稱的提示。

  這遊戲原本還有一部份檢查觀看者輸入的名稱是否正確, 但因筆者在這處主要是說明 array 的操作, 所以略去這檢查部份, 在第 18 章會有這方面詳細舉例。

 

練習-58 隨機在某位置開始顯示 array 內成員

1. 請用瀏覽器開啟示範磁碟中的 array2.htm, 就是以下的網頁, 這資料夾內還有 img0.gif 至 img4.gif。

<html> <body>

<script>
animals=new Array("img0.gif ","img1.gif ","img2.gif ","img3.gif ","img4.gif ")

hints=new Array("6 letters, beginning with d ",
  "
4 letters, beginning with l ", "6 letters, beginning with r ",
  "
5 letters, beginning with s ", "6 letters, beginning with t ")

a = animals.length - 1

do {
x=Math.round(Math.random( )*10 ) }
 while (
x > a )

function
play( )
{ document.
pic.src = animals [x]
  hintsText
= hints[x]
  document.
fm.tx1.value=""
  x
= x + 1
  if (
x == 5 ) { x = 0 }
}
</script>

<img name=pic src="begin.gif " width=100 height=100 border=1>

<form name=
fm>
提示:
<input type=text name=tx1 size=35>
<input type=button value="
顯示動物" onClick="play( ) ">
<input type=button value="
提示"
  onClick="document.
fm.tx1.value=hintsText ">
<p>
請輸入這動物的英文名稱: <input type=text name=tx2>
</form>

</body></html>

2. 網頁開啟後, 請你試驗一下兩個按鈕, 留意出現的動物及提示文字的次序。

 

1. 這處的 animals hints 陣列的設定, 請看前面的解說。

2. 請看這句: a = animals.length - 1 , length是指數目, animals.length 就是 animals 陣列內的成員數目, 這例子是 5, 留意排序是從 0 開始, 但數目則從 1 開始, 這處的 -1使到 a = 4, 即是變為排序的最高值。

3. 以下的兩行是使到第一幅出現的圖片在陣列中某一個隨機位置開始, 而不是每次都從 img0.gif 開始:

do {  x=Math.round(Math.random( )*10 )  }
   while (
x > a )

  這是產生一個隨機數, 若這數值大於4就不要, 再跳回上一行來產生另一個隨機數, 直至得出 0 至 4 之間的一個數值, 例如得出 2, 第一幅出現的圖片會是 img2.gif, 然後順序顯示下去。

4. 隨後的 play( ) 就是顯示圖示的 function, 有以下用途:

  留意這句: if ( x == 5 ) { x = 0 } , 若顯示的圖片排序等於 5 , 即是 images[5] , 陣列中是沒有這圖片的, 上句就是將 x 變回 0, 所以會從 images[0] 再開始。

 

 


8.3 Array 的 length

  length 這一個 property 是指數目, 在 array 中使用, 是指一個陣列內的成員數目, 例如以下的 script 是指定 array 的成員數目有 10 個:

colors=new Array(10)
colors[0]="black"
colors[1]="blue"
colors[2]="brown"

  length 是一個 property, 一定要隸屬一個 object, 這處的例子是 colors, 所以這陣列的成員數目是 colors.length。假若這成員數目定了是 10 個, 但名稱只定義了 3 個, 其餘7個就是 undefined。

 

  我們也可用 length 來指定一個陣列的長度, 例如以下陣列有 12 個成員, 假若你只要 8 個, 可使用以下的 script, 這檔案是示範磁碟中的 length.htm

<html> <body>
<script>
colors=new Array("black", "blue", "brown", "coral", "cyan", "gold", "gray", "green", "indigo", "violet", "white", "yellow" )

alert("The color array has " + colors.length + " elements.")

if(
colors.length > 8)  { colors.length = 8  }

alert("
Now the color array has " + colors.length + " elements.")
alert( "
The 9th element is: " + colors[8] )
</script>

</body> </html>

  這網頁有三個對話盒, 第一個告訴你陣列長度是 12, 第二個告訴你長度是 8, 第三個告訴你第 9 個是 undefined。

 

 


8.4  Array 的 methods

  Array 有多個 method, 例如我們設定了一個名為 pictures 的陣列, 就可用 pictures.method( ) 的方法來更改這陣列。

 

1. arrayName.concat( )

  concat 是 concatenation (結合) 的縮寫, 是用來連結兩個 array , 傳回一個新的array, 以下例子有 colors1colors2, 使用 concat 可合併成 colors3, 這檔案是在示範磁碟中的 concat.htm

<html> <body>
<script>
colors1=new Array("red","green","blue","white","black")
colors2=new Array("indigo", "violet", "white", "yellow")
colors3=colors1.concat(colors2)

for (i=0; i <
colors3.length; i++)
  { document.write(
colors3[i] + " <br> " )  }

</script>
</body> </html>

  這例子的 colors3=colors2.concat(colors1) 是將 colors1 放在 colors2 之後, 然後合併成 colors3, 在隨後的 document.write( ), 你可看到 colors3 共有 9 個 elements。

 

2. arrayName.join( )

  這是用來將一列 array 的成員變為文字, 語法是:

arrayName.join(separator)

  arrayName 是我們設定的 array 名稱, separator 是用來分隔各 成員的符號, 預設是 , 請看以下例子, 這檔案是示範磁碟中的 join.htm

<html> <body>
<script>
colors=new Array("red","green","blue","white","black")
x = colors.join( )
y = colors.join( " + " )
document.write (
x + " <p> " )
document.write (
y )
</script>
</body> </html>

  這處有兩個 document.write( ), 第一個沒有指明 separator, 會有這結果: red,green,blue,white,black

  第二個 document.write( ) 指定用 + 作 separator, 所以有這結果: red + green + blue + white + black

 

3. arrayName.pop( )

    (Netscape-3 及 IE-4 無效)

  這是將最後一個成員挑出, 並傳回這成員的名稱, array 的 length 也縮少一個, 請看以下例子:

<html> <body>
<script>
colors=new Array ( "red","green","blue","white","black" )
drop = colors.pop( )

for (i=0; i <
colors.length; i++)
  { document.write(
colors[i] + " " ) }

document.write( "<p>
The new length is: " + colors.length )
document.write( "<p> " +
drop + " has been popped" )
</script>
</body> </html>

  請看這句: drop = colors.pop( ) , 這是將 colors 這 array 最後一個成員移除, 並將這成員命名為 drop。隨後的數句是顯示新的 colors 名單、長度及被移除的成員。

 

4. arrayName.push( )

   (Netscape-3 及 IE-4 無效)

  這是在 array 之尾加上新成員, length 也自動加長, 若新加多個成員, push( ) 會傳回最後的一個成員的名稱, 請看以下例子:

<html> <body>
<script>
colors = new Array ( "red","green","blue","white","black" )
add = colors.push( "indigo","violet","yellow")

for (i=0; i <
colors.length; i++)
  { document.write(
colors[i] + " " ) }

document.write( " <p>
The new length is: " + colors.length )
document.write( " <p> " +
add + " became the last member. " )
</script>
</body> </html>

  請看這句: add = colors.push("indigo","violet","yellow") , 這是將三個成員加進 colors 這 array, 並將最後的一個成員的名稱傳回, 在這例子, 筆者將這名稱命名為 add, 若要傳回三個成員的名稱, 可分三次進行, 例如:

add1 = colors.push( "indigo")
add2 = colors.push( "
violet")
add3 = colors.push( "
yellow")
document.write( "
New members: " + add1 + " / " + add2 + " / " + add3 )

 

5. arrayName.reverse( )

  這是用來將一個 array 倒排, 新陣列放回原有名稱內, 例如:

<script>
colors = new Array ( "red","green","blue","white","black" )
colors.reverse( )
</script>

  colors.reverse( ) 就是將這 colors array 倒排, 所以 colors[0] 是 black, colors[1] 是 white, colors[4] 是 red。

 

6. arrayName.shift( )

   (Netscape-3 及 IE-4 無效)

  這是將第一個成員挑出, 並傳回該成員的名單, 例如:

<script>
colors = new Array ( "red","green","blue","white","black" )
x = colors.shift( )
</script>

  以上的 script 使到 colors 減少 red 這成員, x 會是 red, length 也縮少一個。這項操作與 pop( ) 相似, 不同的是 pop( ) 挑去最後一個成員, shift( ) 挑去第一個。

 

7. arrayName.slice( )

  slice( ) 是將一個 array 內一列成員抽出, 並傳回一個新的 array, 原有的 array 不變, 語法是: newArray=arrayName.slice(begin,end) , 請看以下例子, 這是在示範磁碟中的 slice.htm

<html> <body>
<script>
colors = new Array ( "red","green","blue","white","black", "indigo","violet","yellow")

shortList=colors.slice(2,6)

for (i=0; i < colors.length; i++)
 { document.write (
colors[i] + " " )  }
document.write( " <p> " )

for (i=
0; i < shortList.length; i++)
 { document.write (
shortList [i] + " " )  }

</script>
</body> </html>

 

1. 請看這句: shortList=colors.slice(2,6)

  留意 array 的排序是從 0 開始, 所以上句的 (2,6) 是從第 3 個成員開始, 至第 7 個成員之前停止, 但不包括第 7 個, 即是包括 colors[2], colors[3], colors[4], colors[5] , 上述的 script 會顯示以下兩行:

red green blue white black indigo violet yellow

blue white black indigo

2. 若不指定停止位置, 例如 shortList=colors.slice(2) , 就會包括至最後的一個成員, 這例子的 shortList 會是 blue white black indigo violet yellow

3. 我們可以使用負數來指定抽取至名單終點前某個位置就停止, 例如 shortList=colors.slice(2,-2) , 就是不包括最後的兩個, 這例子的 shortList 會是 blue white black indigo

 

8. arrayName.splice( )

   (Netscape-3 及 IE-4 無效)

  這是用來在一個陣列中加進新成員, 或減去已有的成員, 利用這 method, 我們可以在一個陣列中, 將已使用過的一個成員從陣列名單中踢走, 就不會重複使用一個名單。splice( ) 有以下語法:

splice(編號, 多少個, "新成員1", ..., "新成員n")

  "編號" 是在陣列中開始變更 (加或減) 的位置, 例如在 colors 陣列中, 編號 5 表示在 colors[5] 這位置開始加進或減去成員。

  "多少個" 是刪去已有的成員數目, 若這數目是 0 則不刪去, 這情況下需要在後指明加進新成員。這 splice( ) 會傳回刪去的成員名單, 但也可不理會這項操作。

  " "新成員1", ... ,"新成員n" " 表示要加進的新成員名單。

 

  請看以下例子, 這是在示範磁碟中的 splice.htm

<html> <body>
<script>
colors = new Array ( "red","green","blue","white","black", "indigo","violet","yellow")
removedList=colors.splice(2, 3, "cyan","gold","gray", "brown" )

for (i=
0; i < colors.length; i++)
 { document.write (
colors [i] + " " ) }
document.write( " <p> " )

for (i=
0; i < removedList.length; i++)
 { document.write (
removedList [i] + " " ) }

</script>
</body> </html>

 

  請用 Netscape-4來看這網頁, 留意這句:

 

  第一個 document.write(colors [i]+ " ") 有這列顯示:

red green cyan gold gray brown indigo violet yellow

 

  留意原本的 colors[2]colors[3]colors[4] 不見了, 在 colors[2] 的位置加進了 cyan、gold、gray、brown 這四個成員。

  第二個 document.write(removedList [i] + " " ) 顯示刪除名單: blue white black

 

練習-59 隨意顯示陣列內成員

  在 練習-58 的例子, 筆者使用隨機的方式, 在陣列中某位置開始, 順序顯示該陣列的成員。在這練習, 筆者使用另外一個取樣方式, 這是隨機顯示一幅圖片, 顯示完後, 這圖片就從陣列中剔除, 然後再取機顯示另一幅圖片, 顯示完後又剔除, 這過程重複, 直至全部圖片顯示完畢。

1. 請你用 Netscape-4 或以上的版本開啟示範碟中的 array3.htm, (Netscape-3及IE-4無效) , 這網頁有以下內容:

<html> <body>
<script>

animals=new Array("img0.gif ","img1.gif ","img2.gif ","img3.gif ","img4.gif ")
hints=new Array("6 letters, beginning with d ", "4 letters, beginning with l " ,
  "
6 letters, beginning with r ", "5 letters, beginning with s ",
  "
6 letters, beginning with t ")

function play( )
{ if (
animals.length==0 )
   { document.
pic.src="end.gif"
     hintstext
=""
     document.
fm.tx1.value="" 
   }

 else { do { if (animals.length==0)   break
          x
=Math.round(Math.random( )*5 )  }
     while (
x > (animals.length-1) )

     document.pic.src=animals[x]
     hintstext
=hints[x]
     animals
.splice(x,1)
     hints
.splice(x,1)
     document.
fm.tx1.value=""
   }
}
</script>

<img name=pic src="begin.gif" width=100 height=100 border=1>

<form name=
fm>
提示: <input type=text name=tx1 size=35>
<input type=button value="
顯示動物" onClick="play( ) ">
<input type=button value="
提示"
  onClick="document.
fm.tx1.value=hintstext ">
<p>
請輸入這動物的英文名稱: <input type=text name=tx2>
</form>

</body></html>

2. 這處有五幅圖片, 若順序顯示會有以下五種動物: donkey、lion、rabbit、shark、turtle, 請你一路記下這五個動物出現的次序, 顯示完畢, 會有 "GAME OVER" 的顯示。

3. 請重新載入這網頁, 然後按 [顯示動物] 的按鈕, 再記下這五個動物出現的次序, 留意是否與上次不同。

4. 請你重新載入這網頁, 在未按 [顯示動物] 前, 就按 [提示], 這是顯示 hintstext 的文字, 你應見到提示錯誤的對話盒, 告訴你 hintstext 還未定義, 原因是 hintstext=hints[x] 這句是在 play( ) 這 function 內, 而這 function 還未開始。

  請你將這 array3.htm 從示範磁碟複製去硬碟, 修改這檔案, 使到觀看者在載入這網頁後立刻按 [提示], 在 document. fm.tx1.value 這文字框內會有 "請先按 [顯示動物] 按鈕" 這句出現, 又或是這 [提示] 按鈕在這情況下沒有反應。

5. 今次產生隨機數的是以下三句:

do {  if (animals.length==0)   break
   x=Math.round(Math.random( )*
5 )   }
 while (
x > (animals.length-1) )

  當我們使用 while loop 時, 要小心無止境的迴圈 (endless loop), 這處請留意 if (animals.length==0) break 這句, 若沒有這句, 當陣列名單是 0 時, x > 0 永遠是 TRUE, 所以這個 loop 會不停地進行, 雖然不會引致當機, 但因 CPU 不停地工作, 整個系統會變得緩慢。

  請你在上述的網頁中刪去 if (animals.length==0) break 這句, 然後在 Netscape-4 載入這網頁, 按 [顯示動物] 這按鈕直至全部動物顯示完畢, 這時請你留意電腦機身中的硬碟 (HDD) 的顯示燈會當閃動, 電腦操作速度顯著減慢, 例如由一個視窗轉去第二個視窗需時十多秒, 你應該試試這經驗, 在試用有 while loop 或 for loop 的網頁時, 遇到這些象徵, 就知是迴圈有問題。

 

  因為 IE 不支援 splice( ) 這個 method, 你可使用其他方法來代替, 使到兩類瀏覽器都可產生同樣的效果。(請看 18.4 的一節。)

 

9. arrayName.sort( )

  這用來將一個陣列根據字母來排序, 排序後的陣列放回原有的名稱內, 請看以下例子:

<html> <body>
<script>
animals = new Array("lion","shark","rabbit","turtle","donkey")
animals.sort( )
document.write(
animals.join( " , " ) )
</script>
</body> </html>

這會顯示 donkey , lion , rabbit , shark , turtle

 

10. arrayName.toString( )

  這是將一個陣列 (或任何一個物件名稱) 變為文字, 並造出一個新的文字物件, 原有陣列不變, 請看以下例子:

<html> <body>
<script>
animals = new Array("lion","shark","rabbit","turtle","donkey")
x=animals.toString( )
document.write(
x )

document.write(" <p>")

for (i=
0; i < animals.length; i++)
  { document.write ( animals[i] + " " ) }
</script>
</body> </html>

  以上 script 會將 animals 這陣列變為文字, 並命名為 x , 所以 document.write(x) 會顯示: lion,shark,rabbit,turtle,donkey, 每個名稱自動用 , 來分隔。

  第二個 document.write( ) 會顯示原有陣列。

  toString( ) 除了在陣列中使用, 也可用於數字上, 請看Math object的一章 (P. 380 )。

 

11. arrayName.unshift( )

   (Netscape-3 及 IE-4 無效)

  這是在陣列中首位置加進一或多個成員, 並傳回該陣列的新長度, 語法是:

arrayName.unshift("新成員1" ,..., "新成員n")

  例如:

<script>
colors = new Array ( "red","green","blue","white","black" )
x=colors.unshift("orange","brown")
</script>

  以上的 script 使到 colors 變成 orange, brown, red, green, blue, white, black, x 會是 7。


( 第 8 章完 )