2015-06-02 2 views
1

Как вы перемещаете массив в PHP, но сохраняете порядок тасования, когда элемент вставлен или удален как mysql-порядок по rand (seed)? Вид алгоритма Shuffle Fisher-Yates, который игнорирует длину массива.PHP shuffle как mysql order by rand (seed)

Давайте предположим, что у вас есть массив с 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.

Добавление элемента Е к списку:

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, В, С, Е, А.

Fisher-Yates предоставит совершенно другой порядок, когда вы добавите элемент «D» в массив, а порядок mysql по rand (seed) будет вставлять элемент «D» где-то в уже отсортированном отсортированном списке.

+0

Вы имеете в виду: Вы берете начальный список и "перетасовать его. Затем, в качестве отдельных шагов, вы вставляете или удаляете элементы в «случайных позициях», но никогда не перетасовываете список снова? –

+0

Можете ли вы поделиться тем, чего вы пытаетесь достичь? – Populus

+0

Допустим, у меня есть 80 списков продажи автомобилей премиум-класса, и я показываю 10 на страницу. Мне нужно, чтобы они были случайными в течение дня (seed = текущий день), но когда клиенты добавляют новые листинги, я хочу сохранить один и тот же случайный порядок и вставлять новые списки среди других, не придавая новым элементам больше веса, в противном случае все клиенты будут удалять/вставлять свои списки, чтобы попасть на вершину. – nookie

ответ

2

Вы можете имитировать сортировки по рандов поведение аналогично этому:

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