常見於:標籤雲排行、熱門搜尋關鍵字、日誌 IP 統計、推薦系統特徵提取等場景。
<?php
function mostRepeatedValues(array $array, int $limit = 0): array
{
if (empty($array)) return [];
// 1. 統計每個值出現次數 → ['value' => count]
$counts = array_count_values($array);
// 2. 依次數由大到小排序,保持鍵值關聯
arsort($counts);
// 3. 可選:只取前 $limit 個
if ($limit > 0) {
$counts = array_slice($counts, 0, $limit, true);
}
return $counts;
}
// 測試資料
$data = [1, 1, 1, 54, 3, 4, 3, 4, 3, 14, 3, 4, 3, 7, 8, 9, 12, 45, 66, 5, 7, 8, 9, 2, 45];
// 取前 5 高頻
print_r(mostRepeatedValues($data, 5));
Array
(
[3] => 5
[4] => 3
[1] => 3
[9] => 2
[45] => 2
)
說明:數字3出現 5 次居首,4與1並列 3 次,9、45各 2 次。
// 陣列中每個元素為關聯陣列,統計某欄位值頻率
$users = [
['name' => 'Alice', 'city' => 'Taipei'],
['name' => 'Bob', 'city' => 'Taichung'],
['name' => 'Cathy', 'city' => 'Taipei'],
['name' => 'David', 'city' => 'Kaohsiung'],
];
$cities = array_column($users, 'city'); // ['Taipei','Taichung','Taipei','Kaohsiung']
print_r(mostRepeatedValues($cities, 3));
// Array ( [Taipei] => 2 [Taichung] => 1 [Kaohsiung] => 1 )
| 資料量 | 時間複雜度 | 空間複雜度 | 建議 |
|---|---|---|---|
| < 10 萬 | O(n log n) — 排序主導 | O(k) — k 為唯一值數量 | 直接使用內建函數,極快 |
| 10 萬 ~ 100 萬 | O(n log n) | O(k) | 注意記憶體峰值,必要時分批處理 |
| > 100 萬 | O(n log k) — 堆排序/Top-K | O(k) | 改用 SplMaxHeap 或 Redis Sorted Set 統計 |
function topKFrequency(array $array, int $k): array
{
$counts = [];
foreach ($array as $v) {
$counts[$v] = ($counts[$v] ?? 0) + 1;
}
// 維護大小為 k 的最小堆
$heap = new SplMinHeap();
foreach ($counts as $value => $freq) {
$heap->insert(['freq' => $freq, 'value' => $value]);
if ($heap->count() > $k) $heap->extract();
}
$result = [];
while (!$heap->isEmpty()) {
$top = $heap->extract();
$result[$top['value']] = $top['freq'];
}
return array_reverse($result, true); // 由大到小
}
此法時間複雜度 O(n log k),空間 O(k),適合百萬級以上資料且只需 Top-K。
對於絕大多數中小型專案,array_count_values() + arsort() + array_slice() 三連招最簡潔、可讀性最高、效能足夠。僅當資料量達百萬級且記憶體敏感時,才需引入堆排序或外部存儲(Redis/Mysql)聚合統計。