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

PHP array_udiff_assoc() 詳解:帶鍵名比較的自定義回調差集運算

     編輯:PHP 綜合知識

函數定位

array_udiff_assoc() 用於比較兩個或多個陣列的「鍵名」與「值」,並返回僅存在於第一個陣列中的鍵值對 (差集)。比較邏輯由使用者提供的回調函數決定,適合物件、複雜資料結構或需特定比較規則 (如大小寫不敏感、浮點數容差) 的場景。

語法簽名

array_udiff_assoc(
    array $array1,
    array $array2,
    array ...$arrays,
    callable $value_compare_func
): array
  • $array1:基準陣列,結果來源。
  • $array2, ...:比較陣列。
  • $value_compare_func:回調 func(mixed $a, mixed $b): int,回傳 < 0、= 0、> 0 分別代表 $a 小於、等於、大於 $b。
  • 回傳:包含差集鍵值對的陣列,保留原鍵名。

關鍵特性

  1. 鍵名參與比較:不同於 array_udiff() 僅比較值,本函數同時檢查鍵名是否相同。
  2. 單層比較:僅檢查第一維。多維陣列需自行遞迴或針對特定子陣列呼叫。
  3. 回調彈性:可實現物件屬性比較、字串正規化比較、日期時間比較等任意邏輯。

實戰範例:物件屬性比較

class CR {
    private int $val;
    public function __construct(int $v) { $this->val = $v; }
    public static function cmp(CR $a, CR $b): int {
        return $a->val <=> $b->val; // PHP 7+ 太空船運算子
    }
}

$a = [
    '0.1' => new CR(9),
    '0.5' => new CR(12),
    0     => new CR(23),
    1     => new CR(4),
    2     => new CR(-15),
];

$b = [
    '0.2' => new CR(9),   // 值相同但鍵名不同 → 視為差異
    '0.5' => new CR(22),  // 鍵名相同但值不同 → 差異
    0     => new CR(3),   // 鍵名相同值不同 → 差異
    1     => new CR(4),   // 鍵名、值皆同 → 不在差集
    2     => new CR(-15), // 鍵名、值皆同 → 不在差集
];

$result = array_udiff_assoc($a, $b, [CR::class, 'cmp']);

print_r($result);
/* 輸出:
Array
(
    [0.1] => CR Object ( [val:private] => 9 )
    [0.5] => CR Object ( [val:private] => 12 )
    [0] => CR Object ( [val:private] => 23 )
)
*/

解析:'1' => CR(4) 於兩陣列鍵名、值皆同,故被排除;'0.1' => CR(9) 與 '0.2' => CR(9) 值同但鍵名異,視為差異保留。

進階用法:多維陣列遞迴比較

function array_udiff_assoc_recursive(array $a1, array $a2, callable $cmp): array
{
    $diff = array_udiff_assoc($a1, $a2, $cmp);
    foreach ($diff as $k => $v) {
        if (is_array($v) && isset($a2[$k]) && is_array($a2[$k])) {
            $diff[$k] = array_udiff_assoc_recursive($v, $a2[$k], $cmp);
            if (empty($diff[$k])) unset($diff[$k]);
        }
    }
    return $diff;
}

常見陷阱與避坑指南

陷阱說明對策
回調回傳非整數回傳 bool/float 會隱性轉型,導致邏輯錯誤嚴格回傳 -1/0/1 或使用 <=>
大量資料效能回調函數會被頻繁呼叫,複雜邏輯拖慢速度簡化比較邏輯、考慮預先正規化鍵值
鍵名型別差異'1' (string) vs 1 (int) 視為不同鍵資料預處理統一鍵名型別
遞迴深度PHP 預設遞迴限制可能不足調整 xdebug.max_nesting_level 或改迭代

函數家族對照表

函數比較鍵名比較值比較方式
array_diff_assoc是是內建 ===
array_udiff否是回調
array_udiff_assoc是是回調
array_diff_uassoc是是鍵名回調、值內建
array_diff_ukey是否鍵名回調

結語

array_udiff_assoc() 是處理結構化資料差異比對的利器。掌握「鍵名+值雙重檢查」與「回調函數邏輯設計」兩大核心,即可靈活應對物件陣列去重、設定檔變更偵測、API 回應差異分析等進階需求。記住:善用 <=> 簡化比較邏輯,必要時封裝遞迴版本處理多維結構。

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