<?php
$items = ['蘋果', '香蕉', '橘子', '葡萄', '芒果'];
$keys = array_rand($items, 3); // 取 3 個不重複鍵
$result = array_intersect_key($items, array_flip($keys));
// 或 PHP 7.1+ 直接
$result = array_intersect_key($items, array_flip(array_rand($items, 3)));
print_r($result);
/*
Array
(
[1] => 香蕉
[3] => 葡萄
[4] => 芒果
)
*/
?>
注意:array_rand() 回傳鍵而非值,且不重新索引。
<?php
$items = ['A','B','C','D','E','F'];
shuffle($items); // 原地打亂,鍵重新索引 0..
$sample = array_slice($items, 0, 3); // 取前 3
print_r($sample); // 如 [D, A, F]
?>
簡潔但會修改原陣列,需先複製 $copy = $items; shuffle($copy);。
原文提供的類別實作邏輯正確但可簡化。現代寫法:
<?php
function randomSample(array $population, int $n): array {
$n = min($n, count($population));
$keys = array_keys($population);
$result = [];
for ($i = 0; $i < $n; $i++) {
$randIdx = random_int($i, count($keys) - 1);
$key = $keys[$randIdx];
$result[] = $population[$key];
// 移除已選鍵(交換到尾部再縮減範圍)
$keys[$randIdx] = $keys[$i];
}
return $result;
}
// 使用
$pool = range(1, 100);
$sample = randomSample($pool, 10);
print_r($sample); // 10 個不重複隨機數
?>
使用 random_int()(CSPRNG)而非 rand(),安全性更高。
<?php
function randomSampleWithReplacement(array $population, int $n): array {
$keys = array_keys($population);
$max = count($keys) - 1;
return array_map(fn() => $population[$keys[random_int(0, $max)]], range(1, $n));
}
?>
| 方法 | 時間 | 記憶體 | 備註 |
|---|---|---|---|
| array_rand + intersect | ~8ms | 低 | 需額外 flip/intersect |
| shuffle + slice | ~12ms | 中 | 修改原陣列/複製 |
| Fisher-Yates 抽樣 | ~3ms | 極低 | 單次遍歷、無額外複製 |
array_rand()shuffle()random_int()ORDER BY RAND() LIMIT n(小表)或 WHERE RAND() < 0.01(大表近似)