在 PHP 開發中,從陣列找出重複值是常見需求。本文介紹兩種截然不同的實作思路:一種善用內建函式,簡潔高效;另一種用巢狀迴圈手寫邏輯,適合理解底層運作。兩種方法各有優劣,可依專案需求選擇。
array_unique 與 array_diff_assoc此法核心邏輯:先用 array_unique 移除重複值取得「唯一值陣列」,再用 array_diff_assoc 比較原陣列與唯一值陣列,差集即為重複值(保留鍵名關聯)。
<?php
function fetchRepeatMembers(array $array): array
{
// 取得去重後的陣列(保留首次出現的鍵名)
$uniqueArr = array_unique($array);
// 比較原陣列與去重陣列,取得被移除的重複項(含鍵名)
$repeatArr = array_diff_assoc($array, $uniqueArr);
return $repeatArr;
}
// 測試資料
$array = ['apple', 'iphone', 'miui', 'apple', 'orange', 'orange'];
$repeatArr = fetchRepeatMembers($array);
print_r($repeatArr);
/*
輸出結果:
Array
(
[3] => apple
[5] => orange
)
*/
?>
特點:程式碼短、可讀性高、效能佳(內建函式經 C 最佳化),但僅回傳「重複的那幾個元素」(含鍵名),若需統計次數或取得所有重複值需額外處理。
for 迴圈手寫比對此法直觀模擬人工比對:外層遍歷每個元素,內層檢查後續元素是否相同,找到即記錄並跳出內層迴圈(避免同一值重複記錄)。
<?php
function fetchRepeatMembersManual(array $array): array
{
$len = count($array);
$repeatArr = [];
for ($i = 0; $i < $len; $i++) {
for ($j = $i + 1; $j < $len; $j++) {
if ($array[$i] === $array[$j]) {
$repeatArr[] = $array[$i];
break; // 同一值只記錄一次
}
}
}
return $repeatArr;
}
// 測試資料同上
$repeatArr = fetchRepeatMembersManual($array);
print_r($repeatArr);
/*
輸出結果:
Array
(
[0] => apple
[1] => orange
)
*/
?>
特點:邏輯清晰、易理解、回傳的是「重複值的列表」(不含原鍵名),但時間複雜度 O(n²),大陣列效能較差;且若同一值重複 3 次以上,仍只記錄一次(因 break),行為與方法一一致。
若需「每個重複值出現的所有位置」,可用 array_count_values 統計次數再篩選:
$counts = array_count_values($array);
$duplicates = array_keys(array_filter($counts, fn($c) => $c > 1));
// 結果:['apple', 'orange']