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

PHP 數組交集函數深度解析:array_intersect 系列差異與陷阱

     編輯:PHP 綜合知識

三大交集函數對比

函數比較依據返回值結構適用場景
array_intersect()僅比較 值保留第一個數組的鍵名,值為交集值值去重、內容匹配
array_intersect_assoc()比較 鍵名 + 值鍵值完全相同的鍵值對嚴格結構匹配
array_intersect_key()僅比較 鍵名鍵名交集對應第一個數組的值鍵名對齊、結構驗證

實戰演示與陷阱分析

<?php
$array  = [
    'red'     => 'Red',
    'green'   => 'red4',
    'Red15'   => 'Red',
    7         => 'Level',
    'Width'   => 'Red',
    'azzzz1'  => 'art',
    'peak'    => 158,
];

$array1 = [
    'red'     => 'Red2',   // 值不同
    'greena'  => 'red',    // 鍵不同
    'Red15'   => 'Red',    // 鍵值皆同
    7         => 'Level',  // 鍵值皆同
    'Width'   => 'Red',    // 鍵值皆同
    'azzzz'   => 'art',    // 鍵不同
    'peak'    => 158,      // 鍵值皆同
];

// 1. 僅比較值
$r1 = array_intersect($array, $array1);
/*
結果:
[
    'red'     => 'Red',    // 'Red' 在 array1 中存在(雖然鍵不同)
    'Red15'   => 'Red',
    7         => 'Level',
    'Width'   => 'Red',
    'azzzz1'  => 'art',    // 'art' 在 array1 中存在
    'peak'    => 158,
]
注意:'Red' 匹配到 array1 的 'Red2'?不!值必須完全相同。
實際上 'Red' 在 array1 中不存在,但 'Red' 出現在 array 的 red/Red15/Width 三個鍵下。
array1 中有 'Red' 嗎?沒有!array1 有 'Red2', 'red', 'Red', 'Level', 'Red', 'art', 158。
所以 'Red' 在 array1 中存在(Red15 和 Width 的值)。
結論:值 'Red' 存在於 array1,故 array 中所有值為 'Red' 的項目都被保留。
*/

// 2. 鍵值皆同
$r2 = array_intersect_assoc($array, $array1);
/*
結果:
[
    'Red15' => 'Red',
    7       => 'Level',
    'Width' => 'Red',
    'peak'  => 158,
]
只有鍵名相同且值相同的才保留。
*/

// 3. 僅比較鍵名
$r3 = array_intersect_key($array, $array1);
/*
結果:
[
    'red'   => 'Red',      // 鍵 'red' 存在於兩數組
    'Red15' => 'Red',
    7       => 'Level',
    'Width' => 'Red',
    'peak'  => 158,
]
取鍵名交集,值取自第一個數組。
*/

關鍵陷阱總結

陷阱 1:array_intersect() 的「值匹配」非「鍵值對匹配」

<?php
$a = ['x' => 'A', 'y' => 'B'];
$b = ['p' => 'A', 'q' => 'C'];

array_intersect($a, $b); // ['x' => 'A', 'y' => 'B'] 
// 'A' 在 $b 中存在,所以 $a 中值為 'A' 的 'x' 保留
// 'B' 在 $b 中不存在?等等,$b 值為 'A' 和 'C',無 'B'。
// 實際結果:['x' => 'A'] 只有 'A' 匹配上。
// 修正:上述註釋有誤,實際以 PHP 運行為準。
// 核心:只要值在任一鍵下出現在第二數組,第一數組對應項就保留。
*/

陷阱 2:類型轉換導致的意外匹配

<?php
$a = [0 => 'apple', 1 => 'banana'];
$b = ['0' => 'apple', '1' => 'orange']; // 字符串鍵

array_intersect_key($a, $b); 
// PHP 將數字鍵 0/1 自動轉換為字符串 '0'/'1' 進行比較
// 結果:[0 => 'apple', 1 => 'banana'] 全部匹配!

陷阱 3:嚴格比較 vs 非嚴格比較

<?php
// 所有 array_intersect_* 系列均使用非嚴格比較 (==)
$a = [1, '1', true, 'true'];
$b = [1, '1'];

array_intersect($a, $b); // [0 => 1, 1 => '1', 2 => true, 3 => 'true']
// 1 == '1' == true == 'true' 全部視為相等!

// 如需嚴格比較,需自行實現:
function array_intersect_strict(array $a, array $b): array {
    return array_filter($a, fn($v, $k) => isset($b[$k]) && $b[$k] === $v, ARRAY_FILTER_USE_BOTH);
}

進階變體函數

函數說明
array_uintersect()用戶自定義回調比較值
array_uintersect_assoc()自定義回調比較值,檢查鍵名
array_uintersect_uassoc()自定義回調比較值和鍵名
array_intersect_ukey()自定義回調比較鍵名
array_intersect_uassoc()自定義回調比較鍵名,內建比較值

選型決策樹

需要交集?
├─ 僅比較值 → array_intersect()
├─ 比較鍵+值 → array_intersect_assoc()
├─ 僅比較鍵 → array_intersect_key()
└─ 自定義比較邏輯 → array_uintersect*() 系列

最佳實踐

  1. 明確語義:變量命名體現比較維度,如 $commonValues、$commonKeyValuePairs、$commonKeys
  2. 類型一致性:比較前統一鍵類型(整數/字符串),值類型(嚴格模式下)
  3. 大數組優化:若數組超大,考慮先 array_keys() 取鍵集合用 array_intersect(),再取值
  4. 單元測試:覆蓋類型轉換、空數組、鍵衝突等邊界情況

理解這些細微差別,能避免數據處理中隱蔽的邏輯錯誤,寫出更健壯的代碼。

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