如何在PHP中对数组进行混洗,但是当插入或删除像rand(seed)的mysql顺序那样的元素时,保留shuffle的顺序呢? 一种Fisher-Yates shuffle算法,它忽略了数组的长度。
假设你有一个包含A,B,C的数组,你可以运行它:
SELECT *
FROM (
SELECT 'A' AS value
UNION
SELECT 'B' AS value
UNION
SELECT 'C' AS value) AS T order by rand(123)
结果将是B,C,A。
现在,如果您将D添加到元素列表中:
SELECT *
FROM (
SELECT 'A' AS value
UNION
SELECT 'B' AS value
UNION
SELECT 'C' AS value
UNION
SELECT 'D' AS value) AS T order by rand(123)
结果将是D,B,C,A。
将元素E添加到列表中:
SELECT *
FROM (
SELECT 'A' AS value
UNION
SELECT 'B' AS value
UNION
SELECT 'C' AS value
UNION
SELECT 'D' AS value
UNION
SELECT 'E' AS value) AS T order by rand(123)
结果将是D,B,C,E,A。
当你将元素“D”添加到数组时,Fisher-Yates将提供完全不同的顺序,而rand(seed)的mysql顺序将在已经随机排序的列表中的某处插入元素“D”。答案 0 :(得分:2)
您可以采用与此类似的方式模拟逐个rand行为:
function sort_by_rand($ary, $seed) {
srand($seed);
$tmp = array_map(function($x) { return [rand(), $x]; }, $ary);
sort($tmp);
return array_map(function($x) { return $x[1]; }, $tmp);
}
结果:
$ary = ['A', 'B', 'C'];
print_r(sort_by_rand($ary, 100)); // CBA
$ary = ['A', 'B', 'C', 'D'];
print_r(sort_by_rand($ary, 100)); // CBAD
$ary = ['A', 'B', 'C', 'D', 'E'];
print_r(sort_by_rand($ary, 100)); // CBAED