PHP 陣列淺析
PHP 陣列淺析
一、概要
- 簡單介紹及基本使用
- php陣列 常用標準庫函式使用
- php陣列模擬常見資料結構
- php陣列使用須知與注意點
- FAQ
二、簡單介紹及基本使用
- PHP 中的陣列實際上是一個有序對映。對映是一種把 values 關聯到 keys 的型別。
- 通過
<?php $arr = array(1, 2, 3, 4);
便定義了一個普通陣列 - 我們還可以定義關聯陣列
$arr = array('a' => 1, 'z' => 100);
- 如果php版本 >= 5.4 , 我們可以使用更為簡潔的方式定義陣列
$arr = [1, 2, 3, 4];
$arr = ['a' => 1, 'z' => 100];
- php 陣列很強大, 可以定義混合型別陣列
$arr = [1, 'hello' => '11', 'arr' => [1, 'a'=>'b']];
- 關於陣列的訪問操作,可以通過
[index]
訪問:
$arr = [1, 'hello' => '11', 'arr' => [1, 'a'=>'b']]; var_dump($arr[0]); // 1 var_dump($arr['arr']); // [1, 'a' => 'b']
- 也可以通過
[]
修改陣列元素的值
$arr = [1, 'hello' => '11', 'arr' => [1, 'a'=>'b']];
$arr[0] = 'test';
var_dump($arr);
- 你也可以在初始化陣列繼續新增陣列元素
$arr = [1, 2, 3, 4];
$arr[] = 'a'; //追加元素
$arr['test'] = 'b'; // 新增 key, value
- 當然,刪除陣列元素的操作必須支援
$arr = [1, 'hello' => '11', 'arr' => [1, 'a'=>'b']];
unset($arr['hello']);
var_dump($arr['hello']); // null
- 開發中經常需要遍歷陣列, 可使用 foreach :
$arr = [1, 'hello' => '11', 'arr' => [1, 'a'=>'b']];
foreach($arr as $key => $value) {
var_dump($key . ' => ' . $value);
}
更多陣列遍歷的方法請參考php-陣列遍歷
- 陣列之間的比較,陣列無法比較大小, 但可以根據一定條件判斷是否相等
// $a == $b 相等 如果 $a 和 $b 具有相同的鍵/值對則為 TRUE。
// $a === $b 全等 如果 $a 和 $b 具有相同的鍵/值對並且順序和型別都相同則為 TRUE。
$a = [1, 2];
$b = ['1' => 2, 0 => 1];
var_dump($a == $b); // true
var_dump($a === $b); // false
三、實用的陣列工具函式
掌握了陣列的基本操作(定義使用,增刪改查, 遍歷) 之後,你就可以在開發中使用陣列, 但只有這些操作是遠遠不夠的,為了滿足複雜多變的開發場景對陣列操作的需求,PHP 提供了功能強大的一套 Array 操作的函式
- - 獲取陣列長度
$arr = [1, 2, 3];
var_dump(count($arr)); // 3
- 希望判斷一個變數是否是陣列,可以通過 is_array():
$arr = [1, 2, 3];
$notArr = '111';
var_dump(is_array($arr)); // true
var_dump(is_array($notArr)); // false
- 更具key 或者 value, 判斷元素 是否在陣列中
// 判斷key 是否在陣列中
$arr = ['a' => 2, 4];
var_dump(isset($arr['a'])); // true
var_dump(array_key_exists('a', $arr)); // true
// 判斷 value 是否在陣列中
in_array(5, $arr); // false
- 獲取陣列所有鍵(keys)
$arr = ['a' => 2, 4];
$keys = array_keys($arr); // ['a', 1]
- 獲取陣列的所有值 (values)
$arr = ['a' => 2, 4];
$values = array_values($arr); // [2, 4]
- 統計陣列各個元素值出現的次數 可以使用 array_count_values:
$arr = [1, 3, 2, 'a' => 1, 'b' => 2];
var_dump(array_count_values($arr));
/* array(3) {
[1]=>
int(2)
[3]=>
int(1)
[2]=>
int(2)
} */
陣列與陣列之間的操作:陣列可以看做一個集合, 集合間的操作(交集,差集,並集, 補集, 比較等) php 也提供相應的方法實現
- 陣列的合併
$arr1 = ['a' => 1, 2, 'b' => 3];
$arr2 = ['b' => 5, 2];
var_dump( array_merge($arr1, $arr2) );
/* array(4) {
["a"]=>
int(1)
[0]=>
int(2)
["b"]=>
int(5)
[1]=>
int(2)
}
// 你也可以使用 + 操作符, 請注意兩種方法結果的差別
var_dump($arr1 + $arr2); */
- 如果是需要計算兩個或跟多陣列value的交集, 可使用
array_intersect
$arr1 = [1, 2, 3];
$arr2 = [5, 2];
var_dump( array_intersect($arr1, $arr2) ); // [2]
- 陣列的差集 (按值value 和 按key)
$a = [1, 2];
$b = ['1' => 2, 0 => 1, 4];
//array_diff 按照索引 和 值 比較差異
var_dump(array_diff($a, $b));
// array_diff_key() 函式用於比較兩個(或更多個)陣列的鍵名 ,並返回差集
var_dump(array_diff_key($a, $b));
- 如果需要獲取子陣列, 可以通過 array_slice 產生類似 python 切片的效果
$arr = [1, 2, 3, 4, 5, 6, 7, 8];
// 從第3個元素開始, 直到結束
var_dump(array_slice($arr, 2));
// 從第3個元素開始, 長度為4
var_dump(array_slice($arr, 2, 4));
// 從第3個元素開始,到倒數第3個元素
var_dump(array_slice($arr, 2, -2));
// 注意 索引的差別
var_dump(array_slice($arr, 2, -2, true));
- 關於陣列的排序操作,也是比較常見的開發需求,需要注意的是:php排序函式都是直接作用於陣列本身, 而不是返回一個新的有序的陣列。, 以下程式碼提供幾種常見的場景, 更多請參考php對陣列進行排序:
// 按照值(value)升序排序, 索引更新
$arr = [6,'a'=>2, 3, 4, 6, -1, 7, 8];
sort($arr);
var_dump($arr);
// 按照值(value)升序排序, 索引保持
$arr = [6,'a'=>2, 3, 4, 6, -1, 7, 8];
asort($arr);
var_dump($arr);
// 按照值(value)降序排序, 索引保持
$arr = [6,'a'=>2, 3, 4, 6, -1, 7, 8];
arsort($arr);
var_dump($arr);
// 按照 鍵(key)進行升序排序 , 索引保持
$arr = ['a' => 10, 'c' => 1, 'b' => 12];
ksort($arr);
var_dump($arr);
// 按照 鍵(key)進行降序排序 , 索引保持
$arr = ['a' => 10, 'c' => 1, 'b' => 12];
krsort($arr);
var_dump($arr);
// 使用者自定義排序, 根據值(value) , 索引更新
// 請注意:對於自定義的比較函式,
// 在第一個引數小於,等於或大於第二個引數時,
// 該比較函式必須相應地返回一個小於,等於或大於 0 的整數。
function cmp($val1, $val2)
{
if($val1 > $val2) {
return 1;
} elseif ($val1 == $val2) {
return 0;
} else {
return -1;
}
}
$arr = [
'a' => 1,
'A' => 3,
'B' => 2,
];
usort($arr, cmp);
var_dump($arr);
// 根據key 自定義排序規則,請使用 uksort(), 用法同usort()
- 關於陣列與字串之間的操作一般有切割字串,合併陣列元素轉為字串兩種操作,可以藉助explode與implode實現
var_dump(explode(',', "a,a,a,a,a,a")); // 以,為分割符將字串"a,a,a,a,a,a" 切割成陣列
var_dump(implode('-', [1, 2, 3, 4, 5])); //以 - 為 拼接符 將 陣列[1, 2, 3, 4, 5] 拼接成字串
關於php 更多陣列相關的函式, 可以參考 官方文件php陣列函式列表
四、陣列模擬常見資料結構
php 陣列可以模擬常見的資料結構,最顯而易見的便是 對映表 和 字典, 這裡簡單介紹php陣列對棧和佇列的模擬。
- 模擬棧(FILO)
$stack = [1, 2, 3, 4];
//入棧
array_push($stack, -1);
var_dump($stack); // [1, 2, 3, 4, -1]
//出棧
$e = array_pop($stack);
var_dump($e); // -1
var_dump($stack); // [1, 2, 3, 4]
- 模擬佇列 (FIFO)
$queue = [];
//入佇列
array_unshift($queue, 1);
array_unshift($queue, 2);
array_unshift($queue, 3);
array_unshift($queue, 4);
//出佇列
$e = array_pop($queue);
var_dump($e); // 1
$e = array_pop($queue);
var_dump($e); // 2
$e = array_pop($queue);
var_dump($e); // 3
$e = array_pop($queue);
var_dump($e); // 4
五、php陣列使用須知與注意點
- php 陣列 key值 會存在以下強制轉換
- 包含有合法整型值的字串會被轉換為整型。例如鍵名 “8” 實際會被儲存為 8。但是 “08” 則不會強制轉換,因為其不是一個合法的十進位制數值。
- 浮點數也會被轉換為整型,意味著其小數部分會被捨去。例如鍵名 8.7 實際會被儲存為 8。
- 布林值也會被轉換成整型。即鍵名 true 實際會被儲存為 1 而鍵名 false 會被儲存為 0。
- Null 會被轉換為空字串,即鍵名 null 實際會被儲存為 “”。
- 陣列和物件不能被用為鍵名。堅持這麼做會導致警告:Illegal offset type。
因此以下程式碼可能導致意外的結果,請注意以下程式碼的輸出:
$arr = [1, 2, '8' => 3];
$arr[false] = -20;
var_dump($arr); // [-20, 2, '8' => 3]
$arr[8] = 20;
var_dump($arr); // [-20, 2, 8 => 20]
$arr[8.7] = 15;
var_dump($arr); // [-20, 2, 8 => 15]
$arr["8.7"] = 10;
var_dump($arr); // [-20, 2, 8 => 10]
$arr[$val] = 5; // 注意$val之前為宣告,因此預設值為null, 陣列key為null時會被轉為""空串
var_dump($arr); // [-20, 2, 8 => 10, "" => 5]
$arr[bar] = 6; // 識別符號被轉化為 'bar'
var_dump($arr); // [-20, 2, 8 => 10, "" => 5, 'bar' => 6]
- 關於php陣列的型別轉換
php陣列可以將其他一切型別轉為陣列,轉化的效果請參考一下程式碼,重點觀察對 null 和 object物件的轉化:
$var = true;
var_dump((array)$var);
/* array(1) {
[0]=>
bool(true)
}*/
$var = 1;
var_dump((array)$var);
/* array(1) {
[0]=>
int(1)
}*/
$var = 1.1;
var_dump((array)$var);
/* array(1) {
[0]=>
float(1.1)
}*/
$var = "111";
var_dump((array)$var);
/* array(1) {
[0]=>
string(3) "111"
}*/
$var = null;
var_dump((array)$var); // 返回空陣列
/* array(0) {
} */
class Cls { public $a = 1; protected $b = 2; private $c = 3; }
var_dump((array)(new Cls)); // 可見性不同 key值格式有所不同
/* array(3) {
["a"]=>
int(1)
["*b"]=>
int(2)
["Clsc"]=>
int(3)
} */
關於PHP型別轉換的瞭解,請參考PHP-型別轉換的判別
六、FAQ
- 如何新增陣列元素更為高效?
array_push($arr, key, value)
or$arr[key] = value
?
答: 後者更為高效, 更多細節請參考官方資料
- isset or array_key_exists() ?
答:
- 對於存在key的陣列,如果 對應的value = null ,
isset($arr[key])
會返回 false;而對於array_key_exists
只要對應key存在就會返回true; - 然而在效率方面,
isset
效率 高於array_key_eixsts
在判斷陣列元素是否存在的最佳實踐如下:
if (isset($arr[$key]) or array_key_exists($key, $arr)) {
...
}
- 數組合並
+
和array_merge
的區別?
答:可以參考該資料
array_diff
與==
的異同?
答:語義有所差別, 陣列的相等比較 推薦只使用 ==
- 遍歷方式那種更高效?
答:foreach 方式 遍歷 最為高效
轉載地址:PHP 陣列淺析