# 3. 使用陣列
{%hackmd QnyEFBdERZebn4iQDXNPnA %}
## 本章重點:陣列的用法
## 01 什麼是陣列?
- 可以儲存一組或一系列值的變數
- 陣列儲存的值 => 稱為陣列元素
- 陣列元素 => 都有索引
## 02 數值索引陣列
### 陣列初始化
- 兩種方式:
```php=
$products = array('Tires', 'Oil', 'Spark Plugs');
//PHP5.4後,更簡短用法
$products = ['Tires', 'Oil', 'Spark Plugs'];
-----------------------------------------------
//可以使用range()儲存升冪排序的數字序列
$numbers = range(1, 10);
//建立一個numbers的陣列,裡面有1-10的數值元素
$odds = range(1, 10, 2);
//第三個參數可以設定間格大小
//得到1-10的奇數
$letters = range('a', 'z');
//也可以使用字元
```
### 存取陣列內容
- 逐個
```php=
$products[0] === $products{0}; //true
//可以使用[], {}來存取陣列裡的變數
```
- 列舉:使用for迴圈
```php=
for($i = 0; $i < 3; $i++){
echo $products[$i]." ";
}
```
### 使用不同索引值的陣列(Dict)
- 陣列初始化
```php=
$prices = array('Tires' => 100, 'Oil' => 10, 'Spark Plugs' => 4);
//以 "=>"建立Dic的鍵-值關係
//產品名稱為鍵(key),價格為值(value)
```
- 存取陣列元素
```php=
$prices['Tires'] //得到100
```
### 使用迴圈
- 使用foreach 或 each() 或 list()
```php=
//使用foreach()
foreach($prices as $key => $value){
echo $key." - ".$value."<br />"
}
//使用each()
while ($element = each($prices)){
echo $element['key']." - ".$element['value'];
echo "<br />"
}
//使用 list 與 each結合
while(list($product, $price) = each($prices)){
echo $product." - ".$price."<br />"
}
//使用each()時,若要重複使用該陣列記得使用:
reset($prices)
```
### 陣列運算子
- \+(聯集)
- \+ 會對純量進行加法,對陣列進行聯集
- $a + $b => 會嘗試將$b元素加到$a。若$b元素的鍵在$a已出現, 它們就不會被加入。
- \==
- \===
- \!=
- \<> => 與!=相同
- \!==
### 多維陣列
- 二維
![](https://i.imgur.com/nCyrZht.jpg)
```php=
//二維陣列初始化
$products = array( array('TIR', 'Tires', 100),
array('OIL', 'Oil', 10),
array('SPK', 'Spark Plugs', 4));
//取值
for ($row = 0; $row < 3; $row++){
for ($column = 0; $column < 3; $column++){
echo '|'.$products[$row][$column];
}
echo "|\n";
}
- 三維
![](https://i.imgur.com/4rt3FXh.jpg)
- 三維資料初始化
![](https://i.imgur.com/Zdo81D3.jpg)
- 三維資料取值
```php=
//$categories[$layer][$row] => 先取產品種類,再取產品,最後取產品特性
for($layer = 0; $layer < 3; $layer++){
echo 'Layer'.$layer."<br />";
for($row = 0; $row < 3; $row++){
for($column = 0; $column < 3; $column++){
echo '|'.$categories[$layer][$row][$column];
}
echo '|<br />'
}
}
```
## 03 排序陣列
### 使用sort()
- 由小到大排序
```php=
//字母排序
$products = array('Tires', 'Oil', 'Spark Plugs');
sort($products);//排序後:Oil, Tires, Spark Plugs
//數字排列
$prices = array(100, 10, 4);
sort($prices);//排序後:4, 10, 100
//注意:sort()會區分大小寫,A<Z, Z<a
$alphabet = array('A', 'a', 'z', 'Z');
sort($alphabet);//排序後:A, Z, a, z
var_dump($alphabet);
//sort()有第二個參數
sort($products, SORT_STRING & SORT_FLAG_CASE);
//可以忽略大小寫 'a'與'A'視為相同
```
### Dict排序 => 使用asort(), ksort()(用法與sort()相同)
- asort() => 使用值排序
- ksort() => 使用鍵排序(key sort)
### 反向排序 => 由大到小排序
- rsort() => reverse sort
- arsort() => ar + sort
- krsort() => kr + sort
### 排序多維陣列
- 使用array_multisort()
- 使用陣列的第一個項目做排序,使用升冪排序
![](https://i.imgur.com/e50Rncy.jpg)
### 自訂的排序
- 使用usort => user sort(自訂義比較函數)
```php=
function compare($x, $y){
if ($x[2] == $y[2]){
return 0;
} else if ($x[2] < $y[2]){
return -1;
} else {
return 1;
}
}
usort($products, 'compare');
//使用$product的價格當作排序標準
```
## 04 重新排序陣列
### 使用shuffle()
- 隨機選擇
```php=
shuffle($pictures);
```
- 反向排序
```php=
//array_reverse()
$numbers = range(1, 10);
$numbers_rev = array_reverse($numbers);
print_r($numbers_rev);
//for-loop 寫反向 並使用array_push將新的元素加到陣列結尾
$numbers = array();
for($i=10; $i>0; i--){
array_push($numbers);
}
//直接使用range()進行反向建立
$numbers = range(10, 1);
$numbers = range(10, 1, -1);//第三個參數可以定義間隔數
```
## 05 從檔案載入陣列
- 可以使用exploit()切割字串
```php=
$line = explode("\t", $to_be_processed_strings);
```
- 注意其用法
- 發現
- exploit的第一個參數有決定性的因素影響是否成功切割字串。exploit字串切割的時候,字串與切割符號要一致
- 從檔案存取文字,其預設文字是**單引號**
- [參考連結](https://blog.csdn.net/wm31898/article/details/98187535)
## 06 其他陣列操作
### 陣列中巡覽
- each($array_name)
- current($array_name) => 回傳第一個元素
- reset($array_name) => 會將指標移回第ㄧ個元素
- end($array_name) => 會將指標移到陣列結尾
- next($array_name) => 將指標往下一個移動
- prev($array_name) => 與next()相反
```php=
//反向順序顯示陣列
$array = array(1, 2, 3);
$value = end($array);
while($value){
echo "$value<br />";
$value = prev($value);
}
```
### 對陣列中每一個元素套用任何函式
- array_walk()
```php=
//以某種指定格式顯示變數
function my_print($value){
echo "$value<br />";
}
array_walk($array, 'my_print');
------------------------------------
//修改陣列裡的值
function my_multiply(&$value, $key, $factor){
$value *= $factor;
}
array_walk($array, 'my_multiply', 3);
//&表示$value會以址傳遞。以址傳遞可以讓函式修改陣列的內容
```
### 計算陣列元素的數量
- count() => 計算陣列裡的元素個數
- sizeof() => count()別名
- array_count_values(\$array) => 計算每個不同值在$array出現的次數
```php=
$array = array(4, 5, 1, 2, 3, 1, 2, 1);
$ac = array_count_values($array);
//[4] => 1
//[5] => 1
//[1] => 3
//[2] => 2
//[3] => 1
```
### 將陣列轉換成純量變數(Dict)
- extract() => 以陣列的鍵值為名建立純量變數。變數的值為陣列內的值。
```c=
//原型:
extract(array var_array [, int extract_type] [, string prefix]);
```
- 用法
```php=
$array = array('key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3');
extract($array);
echo "$key1 $key2 $key3";
//輸出:value1 value2 value3
```
- 為變數自動加上前置詞 => EXTR_PREFIX_ALL
```php=
$array = array('key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3');
extract($array, EXTR_PREFIX_ALL, 'my_prefix');
echo "$my_prefix_key1 $my_prefix_key2 $my_prefix_key3";
```