380 likes | 500 Views
*教科書投影片同教科書受著作權保護,僅供教師作為授課用途。學校教師得使用投影片,於授課期間,搭配用書進行教學;由於投影片極易重製、列印、出版,為避免第三人(含學生)因不知情而發生侵權行為,請支持與協助不將教學投影片以任何型式移轉予第三人使用。如有特殊需求,請向出版社申請授權協議。. Chapter 8 陣列. 在第五章最後介紹 PHP 的變數資料型態時,曾經大致提過陣列資料型態。這一章將會進一步介紹陣列的使用,包括多維陣列、特別的陣列註標使用方法,以及陣列的函數,包括排序、加總等 … 的操作。. 開始. 離開. 目錄. 8-1 宣告陣列 8-2 陣列的初始化
E N D
*教科書投影片同教科書受著作權保護,僅供教師作為授課用途。學校教師得使用投影片,於授課期間,搭配用書進行教學;由於投影片極易重製、列印、出版,為避免第三人(含學生)因不知情而發生侵權行為,請支持與協助不將教學投影片以任何型式移轉予第三人使用。如有特殊需求,請向出版社申請授權協議。*教科書投影片同教科書受著作權保護,僅供教師作為授課用途。學校教師得使用投影片,於授課期間,搭配用書進行教學;由於投影片極易重製、列印、出版,為避免第三人(含學生)因不知情而發生侵權行為,請支持與協助不將教學投影片以任何型式移轉予第三人使用。如有特殊需求,請向出版社申請授權協議。 Chapter 8陣列 在第五章最後介紹 PHP的變數資料型態時,曾經大致提過陣列資料型態。這一章將會進一步介紹陣列的使用,包括多維陣列、特別的陣列註標使用方法,以及陣列的函數,包括排序、加總等…的操作。 開始 離開
目錄 8-1 宣告陣列 8-2 陣列的初始化 8-3 陣列運算子 8-4 常用的陣列函數 離開 回章首 上一頁 下一頁
8-1 宣告陣列 陣列就是由多個相同資料型態的元素(Element)構成的資料集合,不僅每個元素的資料型態相同,而通常會放在同一個陣列的元素,也是因為每個元素有相同的資料意義。譬如,一個存放每個同學姓名的陣列,它的每個元素都是同學的姓名,資料型態也都是字串。 和其它變數型態一樣,每個陣列型態的變數也都有自己的變數名稱,以便區別陣列裡不同的元素。而要存取陣列裡的某個元素,則還要透過指定的註標(index 或subscript)。取得陣列某元素的格式如下: $陣列名稱[註標] 接下來將透過這一節來介紹不同維度的陣列宣告與如何存取陣列裡的某個元素。 下一節 上一頁 下一頁 回目錄
8-1-1 一維陣列 所謂一維陣列就表示陣列只有一個維度,在取得陣列元素時,只需要用到一個註標。例如:下面記錄學生姓名的一維陣列中,每個元素都是字串型態。 陣列的每個元素分別是:$name[0] 、$name[1] 、$name[2] 、$name[3] 、$name[4]。注意,註標一律是由0 開始使用,而非從1開始。這個$name 陣列有5 個元素,所以陣列的大小是5,註標則是從0 到4。 設定上列陣列元素的值所用的設定敘述如下: $name[0]=”Jerry”; $name[1]=”Cherry”; $name[2]=”Sandy”; $name[3]=”Lisa”; $name[4]=”Jack”; 下一節 上一頁 下一頁 回目錄
8-1-2 二維陣列 有兩個維度的陣列稱為二維陣列。二維陣列在日常生活中很常見,譬如,Excel 工作表就是個二維陣列,它包含行與列,通常在說明某個元素的位置時會先說明列的位置,再說行的位置。 假設用俯瞰的角度將教室裡同學的座位想像一個二維陣列,橫的一排就是列,直的一排就是行,每個元素裡儲存該位同學的姓名。下圖就是個4列 * 4 行的二維陣列: 下一節 上一頁 下一頁 回目錄
8-1-2 二維陣列 要取得二維陣列裡的一個元素,要用兩個註標。先用列的註標,再用行的註標,註標仍由0 開始。從第0 列開始逐列取得每列元素,而在每列裡再依序取得不同行的元素,按此次序可得到下列元素: $name[0][0]、$name[0][1]、$name[0][2]、$name[0][3]、$name[1][0]、$name[1][1]、$name[1][2]、$name[1][3]、$name[2][0]、$name[2][1]、$name[2][2]、$name[2][3]、$name[3][0]、$name[3][1] 、$name[3][2]、$name[3][3]。 下一節 上一頁 下一頁 回目錄
8-1-3 多維陣列 至於多維陣列,則是有多個維度,在取得多維陣列的元素時,也要用多個註標。 假設把3個班級的同學座位表想像成一個3 維陣列,第一個維度是班級,第二個維度是列,第三個維度是行。那麼三個班級坐第1列第3 行的同學姓名分別存在$name[0][1][3] 、$name[1][1][3]、$name[2][1][3] 變數裡。 下一節 上一頁 下一頁 回目錄
8-2 陣列的初始化 陣列的初始值設定有兩種方法 : 一種是為每個陣列元素逐一設定它們的值; 另一種則是透過 array 函數將陣列所有元素的初始值一次設好。 下一節 上一頁 下一頁 回目錄
8-2-1 直接設定 在前一節已有提到如何設定陣列中某個元素的值。和一般變數在設定敘述中設定初始值的方式一樣,只是設定運算子“=”左邊改成陣列元素的變數名稱而已。 例如: $b[0]=4; $b[1]=15; $b[]=8; 上面最後一行程式碼的中,中括號“[ ] ”內並沒有加入註標,那麼PHP 將會自動將設定值加入目前陣列的尾端的下個位置。前面兩個敘述之後,$b[0] 和$b[1] 都已填入初始值了,目前陣列的尾端在$b[1] 的位置。因此 $b[] 會自動視為陣列尾端的下一個位置,也就是$b[2] 的位置。所以 $b[2] 的值會被設為8。 下一節 上一頁 下一頁 回目錄
8-2-1 直接設定 下一節 上一頁 下一頁 回目錄
8-2-2 array 函數設定 另一種設定陣列初始值的方法,是利用 array 函數來宣告。array 函數是用來建立一個新的陣列,參數就是陣列的初始值,回傳值就是建立好的新陣列,通常會在設定敘述裡將它指派給一個變數。array 函數大致上有兩種參數的格式: array(值1, 值2, ……); array(鍵值1=>值1, 鍵值2=>值2, ……); 第一種方式在小括號內設定的值,會依序從陣列註標0 的位置開始填入陣列元素。 而第二種方式則多了鍵值,鍵值可以是字串或整數。若有使用到相同的鍵值,則最後宣告的值會覆蓋掉該鍵值原先設定的對應值。兩種方式可以混合著用,若省略鍵值則會自動將值設到目前為止鍵值最大的元素的下一個位置。 下一節 上一頁 下一頁 回目錄
8-2-2 array 函數設定 先來看看用 array 函數設定一維陣列初始值的例子。 下一節 上一頁 下一頁 回目錄
8-2-2 array 函數設定 下一節 上一頁 下一頁 回目錄
8-2-2 array 函數設定 程式說明: 要特別說明的是第 16 行中,註標 5 的位置已被“Helen”填入了,所以後面的“Michael”和“Jeremy”雖然沒有指定它們的鍵值,還是會自動填入陣列中下一個位置,也就是註標 6 和 7 的位置。至於註標1 的位置,原本是被填入“Mary”,但因為後來的 1=>“Tom”使得註標 1 的值被覆蓋成“Tom”了。 最後第 17 行和 29 行的 print_r 函數可以將陣列中每個元素的鍵值和內容印出來。 下一節 上一頁 下一頁 回目錄
8-2-2 array 函數設定 再來看看用 array 函數設定二維陣列初始值的例子。 下一節 上一頁 下一頁 回目錄
8-2-2 array 函數設定 程式說明: 上面的範例程式 Chap08-03.php 中,$city_US這個二維陣列變數是在宣告美國幾個州的城市名稱。它有兩個維度,第一個維度是州的縮寫,例如:‘CA’代表加州,第二個維度是城市名稱的縮寫,例如:‘BC’代表‘British Columbia’。要存取到‘British Columbia’這個城市名稱,必須指定在陣列的兩個維度註標,也就是$city_US['CA']['BC'],才能存取到該陣列元素的值:‘British Columbia’。 最後用到的 print_r 函數可以將陣列的內容,從第一個維度開始逐一將每個維度內的所有元素的內容逐一印出。 下一節 上一頁 下一頁 回目錄
8-3 陣列運算子 陣列資料型態可以被視為集合(Set)資料型態。不過,雖然集合內的元素次序是不重要的,但陣列裡的元素有它的註標,元素之間是有次序關係的。在使用PHP的陣列運算子比較兩個陣列的元素內容是否相同時,是會比較陣列裡元素的鍵值(或註標)和值的對應組合 (pair)。例如:兩個陣列元素的鍵值與值的對應組合必須是完全相同,那麼“ == ”運算子的比較結果才會是 true。 除了陣列的比較運算子之外,還記得8-2-1 節中曾提過“[]”,它也是陣列運算子。它可以在陣列的下一個位置加一個新的元素,譬如:假如目前陣列 $a的元素目前最後的位置是在註標5,那麼 $a[]=“hello” 的設定敘述會將 $a[6] 的值設為“hello”字串。 下一節 上一頁 下一頁 回目錄
8-3 陣列運算子 現在將陣列所有的運算子整理如下表,其中$a、$b 都是陣列變數: 下一節 上一頁 下一頁 回目錄
8-3 陣列運算子 下一節 上一頁 下一頁 回目錄
8-3 陣列運算子 程式說明: 第7 行是取$a 與$b 的聯集,因為是 $c =$a+$b, 所以是先把 $a 的元素先加到 $c 之後,再把$b 的部份跟$a 鍵值不同的部份加在$c 的後面,至於$b 和$a 鍵值相同的部份並不會將$a 原有的值覆蓋過去。 第11 行是取$b與$a 的聯集,因為是 $d = $b + $a;, 所以是先把 $b 的元素先加到 $d 之後,再加入 $a 的部份。操作方式和第 7 行類似,只是聯集運算子“+”的兩個運算元次序不同,運算的結果也會不同。 下一節 上一頁 下一頁 回目錄
8-3 陣列運算子 下一節 上一頁 下一頁 回目錄
8-3 陣列運算子 程式說明: $list1和 $list2 的元素的鍵值和值的對應關係是一樣的,鍵值 1 對應的都是"orange",而鍵值0 的也都是"apple",所以 “==” 的結果是true。而和它相反的比較運算子“!=” 和 “<>”結果就是相反的false。 但是 $list1 中的元素先是鍵值0 接著是鍵值1,而 $list2 則先是鍵值1 接著是鍵值0,兩者的次序不同。因此“===” 的結果是 false,而和它相反的“!==” 運算子結果就是 true 了。 至於 $list3和 $list4 陣列元素的鍵值和對應的值(雖然資料型態不同)是一樣的,而元素的次序也是一樣,所以“==”的比較結果是true。但是因為 $list3 裡的元素資料型態是整值,$list4 則是字串,兩者的資料型態 不同,所以“===”比較的結果仍然是false。 最後, $list5和 $list6 的元素集合雖然相同,但因為它們的鍵值所對應到的值並沒有完全相同,$list5 的鍵值0是對到10,而 $list6 的鍵值0則是對到30。所以“==”比較的結果已經是false了,不用說“===”比較的結果也會是false。 下一節 上一頁 下一頁 回目錄
8-4 常用的陣列函數 PHP 有許多和陣列相關的函數可以使用。這一節將介紹幾種較有機會使用到的陣列函數使用方法。 如果讀者需要了解更多函數的使用方式,可以上網查閱:http://tw2.php.net/manual/en/funcref.php。 上一節 上一頁 下一頁 回目錄
8-4-1 計算陣列元素個數 計算陣列元素個數的函數是 count,它的函數原型如下: int count (陣列變數名稱) 它的回傳值是整數值,回傳值就是陣列的元素個數。如果小括號內的變數值還沒被初始化,那麼count 函數會回傳0。 上一節 上一頁 下一頁 回目錄
8-4-1 計算陣列元素個數 上一節 上一頁 下一頁 回目錄
8-4-1 計算陣列元素個數 程式說明: 在第7 行和第15 行可看到利用 count 函數取得目前陣列裡元素的個數。在程式裡常需要在迴圈裡針對陣列的每個元素做處理,這時要知道陣列裡有多少個元素就很重要了。如果元素個數是 $cnt_a,那麼所有陣列元素的註標是從0 到 $cnt_a - 1為止。在第9 行for 迴圈裡寫 $i<$cnt_a,代表迴圈會 從 $i=0 執行到 $i=$cnt_a - 1 為止。有關 for 迴圈的語法在接下來的第9 章會有較詳細的說明。 上一節 上一頁 下一頁 回目錄
8-4-2 陣列元素的加總 在前一小節我們看到在範例程式 Chap08-6.php中,要計算陣列內所有元素的加總,是用迴圈一個個去取得陣列裡的元素,然後自行將它相加起來。PHP 提供了array_sum 函數,它的函數原型如下: numberarray_sum (陣列變數名稱) 它會回傳陣列變數元素的數值總和,回傳值是整數或浮點數。 上一節 上一頁 下一頁 回目錄
8-4-2 陣列元素的加總 上一節 上一頁 下一頁 回目錄
8-4-2 陣列元素的加總 程式說明: 是否注意到範例程式 Chap08-7.php 和前一小節的Chap08-6.php 結果一模一樣?但 Chap08-7.php的程式碼簡化了許多,加總陣列元素的地方只要改用array_sum 函數,不需要用迴圈了。將 array_sum函數配合前一小節介紹的 count 函數就可以算出陣列裡元素的平均值。 第15行的round 函數是將浮點數四捨五入到指定的小數位數,第二個參數是指四捨五入到小數點後第幾位數。 上一節 上一頁 下一頁 回目錄
8-4-3 反覆取得陣列各元素 從PHP4 版本開始,就提供了 foreach 函數方便在陣列裡重覆(iterate)取得每個元素做後續處理,譬如列印、加總…等。它的功能和for 或while 之類的迴圈很類似,但 foreach 對於陣列型態的變數提供了更簡單易讀的使用方式來取出每個陣列元素。 foreach 的使用格式有下列兩種: foreach (陣列變數名稱as $value) {敘述}; foreach (陣列變數名稱as $key => $value) {敘述}; 事實上兩種格式只是差在第二種多了取得鍵值 $key 的部份。foreach 會逐一取得陣列裡的每個元素,通常會把取出元素的鍵值或值之後所要做的事寫在foreach迴圈敘述裡,如果有多個敘述則要用大括號將要重覆執行的幾行敘述包圍起來。 foreach 函數中存放值的變數,例如:$value 變數,如果在這變數名稱前加上& 變成了 &$value,還記得這是代表“傳址設定”的意思嗎?$value 變數的記憶體位址會和陣列元素一樣,若更改 $value 變數的值就會連帶影響到陣列元素值。 上一節 上一頁 下一頁 回目錄
8-4-3 反覆取得陣列各元素 上一節 上一頁 下一頁 回目錄
8-4-3 反覆取得陣列各元素 上一節 上一頁 下一頁 回目錄
8-4-3 反覆取得陣列各元素 程式說明: 第5 到9 行定義了自定函數 display_array。它會將傳給它的陣列每個元素的鍵值和對應的值透過foreach 逐一顯示出來。有關自定函數將會在第十章再做介紹。 注意第 15 行的 foreach 裡是用 “&$value”而不是 “$value”,所以第16 行的“$value = $value * 2;”就會使得每個陣列元素值都變成2 倍大。第17 行“unset($value); ”則是為了避免最後當離開這個 foreach 迴圈之後,$value 仍會一直影響著陣列裡的最後一個元素值,透過 unset 指令將它重設以免對後續程式造成不可預期的後果。 第21 到25 行定義二維陣列的初始值,第一維度的元素鍵值分別是 0、2、7,對應的內容分別是三個不同的陣列,陣列的大小也不盡相同。第26 行的foreach 迴圈則是先在外層迴圈逐一取得內層的三個陣列內容並存在 $value1 變數,第28 行的內層 foreach 迴圈則是將外層取出的 $value1 陣列再逐一取出每個元素列印。 上一節 上一頁 下一頁 回目錄
8-4-4 陣列的排序 所謂排序(Sorting)就是將資料由小至大,或由大至小重新排列。PHP的陣列的排序函數有許多個,大都是利用Quicksort 的演算法實作出來的。這一節要介紹其中四個排序函數:sort、asort、rsort、arsort 差別在於sort、asort 是由小到大排序,而rsort、arsort 則是由大到小排序。其中“r”是取自 “Reverse”,“a” 則是取自 “index Association”。 sort/rsort 和 asort/arsort 的差別在於 asort/arsort 函數會保留陣列元素鍵值和值的對應關係,而 sort/rsort 則不會,而且sort/rsort不但不會保留原先的鍵值,還會將鍵值重新由0 開始編號。 這幾個排序函數的使用函數原型都是同一個格式: bool sort/rsort/asort/arsort (陣列變數名稱) 它們的回傳值都是布林值,若執行時正常則回傳true,有錯誤則回傳false。 上一節 上一頁 下一頁 回目錄
8-4-4 陣列的排序 上一節 上一頁 下一頁 回目錄
8-4-4 陣列的排序 上一節 上一頁 下一頁 回目錄
8-4-4 陣列的排序 上一節 上一頁 下一頁 回目錄
8-4-4 陣列的排序 程式說明: 從sort 排序完的結果可以看出來,元素的值是由小到大排序,但鍵值則是被自動重新由0 開始編號了,原來的鍵值已消失了。 從 asort 排序完的結果可以看出來,元素的值同樣已由小到大排序好,但原來的鍵值仍然存在,鍵值和值的對應關係仍維持不變,鍵值 ‘a’ 還是對應到 ‘apple’, ‘b’ 還是對應到 ‘banana’ …等等。 至於 rsort 排序則是元素的值是由大到小排序,但原來的鍵值已不存在,鍵值已被自動重新由0 開始編號了。 最後arsort 也是由大到小排序,但鍵值和值的對應關係仍維持不變,原來的鍵值仍然存在,而鍵值 ‘t’ 還是對應到 ‘teaspoon’, ‘n’ 還是對應到 ‘napkin…等等。 上一節 回目錄 上一頁