PHP shuffle像rand(种子)的mysql顺序

时间:2015-06-02 15:49:50

标签: php mysql random shuffle

如何在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”。

1 个答案:

答案 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