首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP unset vs array_splice:數組刪除元素的行為差異、性能對比與最佳選擇指南

     編輯:PHP 相關知識

PHP 中刪除數組元素最常用 unset() 和 array_splice(),但兩者在索引重排、返回值、性能、適用場景上有本質區別。本文深度對比並給出選型決策樹。

核心差異速覽

| 特性 | unset() | array_splice() | |------|---------------------|----------------------------| | **索引重排** | ❌ 保留原鍵,產生「稀疏數組」 | ✅ 重置數字索引 (0,1,2...) | | **返回值** | void | 被刪除元素組成的新數組 | | **操作對象** | 按鍵名刪除 | 按偏移量/長度刪除 | | **關聯數組** | 完美支持 | 僅重置數字鍵,字符串鍵保留 | | **性能** | O(1) 極快 | O(n) 需移動後續元素 | | **原地修改** | ✅ | ✅ |

行為演示

unset():保留鍵,產生空洞

<?php
$arr = ['a', 'b', 'c', 'd']; // 索引: 0,1,2,3
unset($arr[1]);

var_dump($arr);
/* 輸出:
array(3) {
  [0]=> string(1) "a"
  [2]=> string(1) "c"   // 索引 1 消失,變稀疏
  [3]=> string(1) "d"
}
*/

// 關聯數組完美支持
$assoc = ['x' => 1, 'y' => 2, 'z' => 3];
unset($assoc['y']);
// ['x' => 1, 'z' => 3] 鍵完整保留

array_splice():重排索引,返回被刪元素

<?php
$arr = ['a', 'b', 'c', 'd'];
$removed = array_splice($arr, 1, 1); // 從偏移 1 刪除 1 個

var_dump($removed); // array(1) { [0]=> "b" }
var_dump($arr);
/* 輸出:
array(3) {
  [0]=> "a"
  [1]=> "c"   // 索引重排:0,1,2
  [2]=> "d"
}
*/

// 關聯數組:字符串鍵保留,數字鍵重排
$assoc = ['x' => 1, 'y' => 2, 'z' => 3];
array_splice($assoc, 1, 1); // 偏移 1 刪除 1 個
// 結果:['x' => 1, 'z' => 3] — 字符串鍵未變,但順序改變

進階用法對比

按值刪除(需先查找鍵)

<?php
$arr = [10, 20, 30, 40, 50];
$valueToRemove = 30;

// unset 版
$key = array_search($valueToRemove, $arr);
if ($key !== false) unset($arr[$key]);
// 結果:[0=>10, 1=>20, 3=>40, 4=>50] 稀疏

// array_splice 版
$key = array_search($valueToRemove, $arr);
if ($key !== false) array_splice($arr, $key, 1);
// 結果:[0=>10, 1=>20, 2=>40, 3=>50] 緊湊

// 批量刪除特定值
$arr = [1, 2, 3, 2, 4, 2, 5];
$arr = array_values(array_filter($arr, fn($v) => $v !== 2));
// [1, 3, 4, 5] — 一行搞定,推薦

刪除區間範圍

<?php
$arr = ['a','b','c','d','e','f'];

// unset: 需循環
foreach (range(1, 3) as $i) unset($arr[$i]);
// 結果:[0=>'a', 4=>'e', 5=>'f']

// array_splice: 一行
array_splice($arr, 1, 3); // 偏移1,長度3
// 結果:[0=>'a', 1=>'e', 2=>'f']

刪除並插入新元素 (array_splice 獨有)

<?php
$arr = [1, 2, 3, 4, 5];
array_splice($arr, 2, 1, ['x', 'y']); // 索引2刪1個,插入x,y
// 結果:[1, 2, 'x', 'y', 4, 5]

性能基準測試 (10萬元素,刪除中間元素)

<?php
$arr = range(1, 100000);

// unset
$start = microtime(true);
unset($arr[50000]);
echo "unset: " . (microtime(true) - $start) * 1000 . " ms\n";
// ~0.001 ms

// array_splice
$arr = range(1, 100000);
$start = microtime(true);
array_splice($arr, 50000, 1);
echo "array_splice: " . (microtime(true) - $start) * 1000 . " ms\n";
// ~2.5 ms (需移動 5萬個元素)

// array_filter 重建 (按值刪除)
$arr = range(1, 100000);
$start = microtime(true);
$arr = array_values(array_filter($arr, fn($v) => $v !== 50000));
echo "array_filter: " . (microtime(true) - $start) * 1000 . " ms\n";
// ~3.5 ms

性能結論

  • unset():O(1),極快,適合高頻、大數據、按鍵刪除
  • array_splice():O(n),需移動內存,適合需索引緊湊、區間刪除、刪除並插入
  • array_filter() + array_values():O(n),全量重建,適合按值過濾、函數式風格

選型決策樹

```mermaid graph TD A[需要刪除數組元素] --> B{知道鍵名/偏移量?} B -->|是| C{需要索引緊湊連續?} B -->|否,按值刪除| D[array_filter + array_values] C -->|否,允許稀疏/關聯數組| E[unset - 最快 O(1)] C -->|是,數字索引需重排| F{需同時插入新元素?} F -->|是| G[array_splice] F -->|否| H{區間刪除?} H -->|是| G H -->|否,單點| I[array_splice 或 unset+array_values] ```

代碼模板:統一刪除工具函數

<?php
/**
 * 統一數組刪除函數
 * @param array $array 目標數組 (引用)
 * @param int|string|callable $criteria 鍵名/偏移量/回調函數
 * @param int $length 刪除長度 (僅 array_splice 模式)
 * @param bool $reindex 是否重排索引
 * @param array $replacement 替換元素 (僅 array_splice)
 * @return array 被刪除的元素
 */
function array_delete(
    array &$array,
    int|string|callable $criteria,
    int $length = 1,
    bool $reindex = true,
    array $replacement = []
): array {
    if (is_callable($criteria)) {
        // 按值/條件刪除
        $removed = [];
        $array = array_values(array_filter($array, function($v, $k) use ($criteria, &$removed) {
            $match = $criteria($v, $k);
            if ($match) $removed[] = $v;
            return !$match;
        }, ARRAY_FILTER_USE_BOTH));
        return $removed;
    }

    if (is_string($criteria)) {
        // 關聯數組按鍵名
        if (!array_key_exists($criteria, $array)) return [];
        $removed = [$array[$criteria]];
        unset($array[$criteria]);
        if ($reindex) $array = array_values($array);
        return $removed;
    }

    // 數字索引/偏移量
    if ($criteria < 0) $criteria = max(0, count($array) + $criteria);
    if ($criteria >= count($array)) return [];

    if ($reindex || $replacement) {
        return array_splice($array, $criteria, $length, $replacement);
    } else {
        $removed = array_slice($array, $criteria, $length);
        foreach (range($criteria, $criteria + $length - 1) as $i) {
            unset($array[$i]);
        }
        return $removed;
    }
}

// 使用示例
$arr = ['a','b','c','d','e'];
array_delete($arr, 1);                    // 刪除索引1,重排
array_delete($arr, 'key');                // 關聯鍵刪除
array_delete($arr, fn($v) => $v > 'c');   // 條件刪除
array_delete($arr, 1, 2, true, ['x']);    // 區間刪除並插入

補充:array_filter 刪除空值/假值

<?php
$arr = ['a' => 'abc', 'b' => '', 'c' => 'def', 'd' => null, 'e' => 0, 'f' => false];

// 刪除空字符串、null、false、0 (所有假值)
$filtered = array_filter($arr); // 不帶回調默認過濾假值
// ['a' => 'abc', 'c' => 'def']

// 保留 0 和 false,只刪空字符串和 null
$filtered = array_filter($arr, fn($v) => $v !== '' && $v !== null);
// ['a' => 'abc', 'c' => 'def', 'e' => 0, 'f' => false]

總結

  1. 按鍵刪、允許稀疏、追求極致性能 → unset($arr[$key])
  2. 需索引緊湊、區間刪除、刪除並插入 → array_splice($arr, $offset, $len, $replacement)
  3. 按值/條件過濾、函數式風格 → array_values(array_filter($arr, $callback))
  4. 關聯數組刪除鍵 → unset($arr['key']) (最語義化、最快)
  5. 統一封裝 → 根據項目規模封裝 array_delete() 工具函數,統一團隊風格

理解底層差異,根據場景選擇正確工具,是從「能跑通」進化為「高性能、可維護」的關鍵一步。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved