問題:unset() 不重建索引
<?php
$arr = ['apple', 'banana', 'cat', 'dog'];
unset($arr[2]); // 刪除 'cat'
print_r($arr);
/*
Array
(
[0] => apple
[1] => banana
[3] => dog <-- 索引斷層,第三格消失
)
*/
解法:array_splice() 刪除並重建
<?php
function arrayRemove(array &$arr, int $offset): void {
array_splice($arr, $offset, 1);
}
$arr = ['apple', 'banana', 'cat', 'dog'];
arrayRemove($arr, 2); // 刪除索引 2
print_r($arr);
/*
Array
(
[0] => apple
[1] => banana
[2] => dog <-- 索引重建為 0,1,2
)
*/
array_splice() 完整語法與變體
array_splice(array &$array, int $offset, int $length = null, mixed $replacement = []): array
- 回傳**被移除的元素陣列**
$offset:正數從前算、負數從後算
$length:省略 = 移除到結尾;正數 = 移除筆數;負數 = 保留尾部筆數
$replacement:插入的新元素 (單一值會被包成陣列)
常見操作範例
| 操作 | 程式碼 | 結果 |
| 刪除第 1 個 | array_splice($a, 0, 1) | 移除首項 |
| 刪除最後 2 個 | array_splice($a, -2) | 保留前面 |
| 替換索引 1~2 為新值 | array_splice($a, 1, 2, ['X', 'Y']) | 原 1,2 被 X,Y 取代 |
| 索引 1 插入新值 (不刪除) | array_splice($a, 1, 0, 'NEW') | NEW 變新索引 1,後面後移 |
| 取得被移除元素 | $removed = array_splice($a, 0, 2) | $removed = 前兩項 |
關鍵字串鍵名陣列行為
<?php
$a = ['a' => 1, 'b' => 2, 'c' => 3];
array_splice($a, 1, 1); // 移除 'b'
print_r($a); // ['a' => 1, 'c' => 3] 字串鍵名**保留**,數值鍵名**重建**
// 注意:PHP 文件註明「數值索引重新編排,字串索引保持不變」
?>
效能提示
- 大陣列 (10萬+) 頻繁 `array_splice` 會重新分配記憶體,考慮改用 **雙向鏈表** (`SplDoublyLinkedList`) 或 **標記軟刪除** 批次重建
- 單純過濾陣列用 `array_filter()` 產生新陣列,再 `array_values()` 重建索引,語意更清晰