---
# System prepended metadata

title: 3. 使用陣列

---

# 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";
    ```

