array_unique() 僅支援一維陣列去重。對多維陣列直接使用會產生 Array to string conversion 警告且結果錯誤。
function multiUnique(array $array): array {
$serialized = array_map('serialize', $array);
$unique = array_unique($serialized);
return array_map('unserialize', $unique);
}
// 測試
$data = [
['id' => 1, 'name' => 'A'],
['id' => 2, 'name' => 'B'],
['id' => 1, 'name' => 'A'], // 重複
];
print_r(multiUnique($data));
// 保留鍵名:[0] => ['id'=>1,'name'=>'A'], [1] => ['id'=>2,'name'=>'B']
原理: 將子陣列序列化為字串 → 去重 → 反序列化還原。
function assocUnique(array $array): array {
$result = [];
foreach ($array as $key => $value) {
if (!in_array($value, $result, true)) { // 嚴格比較
$result[$key] = $value;
}
}
return $result;
}
function unique2D(array $array2D, bool $keepFirstKey = false, bool $keepSubKeys = true): array {
// 記錄一級鍵名
$firstKeys = $keepFirstKey ? array_keys($array2D) : null;
// 記錄二級鍵名(假設所有子陣列鍵名相同)
$subKeys = $keepSubKeys ? array_keys(end($array2D)) : null;
// 降維:子陣列轉字串
$temp = [];
foreach ($array2D as $v) {
$temp[] = implode(',', $v);
}
// 去重
$temp = array_unique($temp);
// 重組
$output = [];
foreach ($temp as $k => $v) {
$newKey = $keepFirstKey ? $firstKeys[$k] : $k;
if ($keepSubKeys) {
$parts = explode(',', $v);
foreach ($parts as $sk => $sv) {
$output[$newKey][$subKeys[$sk]] = $sv;
}
} else {
$output[$newKey] = explode(',', $v);
}
}
return $output;
}
// 測試資料
$data = [
'first' => ['title' => '1111', 'date' => '2222'],
'second' => ['title' => '1111', 'date' => '2222'], // 重複
'third' => ['title' => '2222', 'date' => '3333'],
];
print_r(unique2D($data, true));
// 保留 'first', 'third' 鍵名
| 方法 | 時間複雜度 | 記憶體 | 適用場景 |
|---|---|---|---|
| 序列化法 | O(n) | 中 | 一般關聯陣列、結構不固定 |
| in_array 比較 | O(n²) | 低 | 小資料量、簡單結構 |
| 降維字串法 | O(n) | 中 | 大量二維陣列、需保留鍵名 |
unique()->values()->all(); // Laravel Collection
// 或純 PHP
$unique = array_values(array_unique($data, SORT_REGULAR));
['a'=>1,'b'=>2] !== ['b'=>2,'a'=>1])md5(serialize($v)))作為索引