實際開發中常遇到「從 1~25 中隨機抽取 16 個不重複數字」的需求(如投票系統、抽獎邏輯)。本文提供一個高效、通用的 unique_rand() 函數,並解析其核心優化技巧。
<?php
/**
* 生成指定範圍內不重複的隨機整數陣列
* @param int $min 最小值(含)
* @param int $max 最大值(含)
* @param int $num 需要生成的數量
* @return array 打亂鍵名後的數字陣列
*/
function unique_rand(int $min, int $max, int $num): array {
$return = [];
while (count($return) < $num) {
$return[] = mt_rand($min, $max);
// 「翻翻法」去重:array_flip 兩次利用鍵名唯一性,速度遠快於 array_unique()
$return = array_flip(array_flip($return));
}
// shuffle 重置鍵名為 0~n-1 連續整數,方便後續遍歷
shuffle($return);
return $return;
}
// 使用範例:從 1~25 取 16 個不重複數字並排序輸出
$arr = unique_rand(1, 25, 16);
sort($arr);
echo implode(',', $arr); // 輸出類似:2,3,4,6,7,8,9,10,11,12,13,16,20,21,22,24
array_flip(array_flip($arr)) 利用陣列鍵名不可重複特性,效能遠優於 array_unique()(後者需逐一比對值)。[0=>2, 2=>5, 5=>9]),shuffle() 同時打亂順序並重置為連續數字鍵,避免 foreach 或 for 迴圈踩坑。WHERE id IN (...))$num 接近 $max - $min + 1,建議改用 range() + shuffle() + array_slice(),避免 while 迴圈過多碰撞。掌握此演算法,能以最少代碼解決「不重複隨機抽樣」這類高頻業務痛點,且效能穩健可靠。