Как рандомизировать массив с сохранением рандомного порядка?

Ссылка скопирована
1 ответ

Задача такая, есть многомерный массив состоящий из 300 массивов. Если быть точнее это заполненный повторитель ACF в Wordpress, но суть не меняет - это массив из 300 других массивов. Так как сайт раскопирован на множество копий менять порядок в нем вручную не представляется возможным. Задача такая - нужно чтобы на каждом из сайтов порядок вывода данных из массива был рандомным, но при этом сохранялся в рамках этого сайта. Т.е. на каждой копии его необходимо перемешать, но не перемешивать каждый раз при исполнении. Все функции рандомизации на PHP позволяют перемешивать его в реальном времени - но тогда при каждом обновлении страницы будет новый результат, а мне необходимо просто перемешать массив один раз для каждого сайта с сохранением этого перемешанного значения.

Дополнительно:

И? Что Вы пробовали и что именно не получается?

  • ЕСЛИ нет данных в кэше   перемешать массив    положить данные в кэш КОНЕЦ ЕСЛИ  взять данные из кэша

    ЕСЛИ нет данных в кэше перемешать массив положить данные в кэш КОНЕЦ ЕСЛИ взять данные из кэша

  • Сергей delphinpro, а чего не в ответы?
  • Дмитрий, и то правда.
  • Как рандомизировать массив с сохранением рандомного порядка?

    ЕСЛИ нет данных в кэше   перемешать массив    положить данные в кэш КОНЕЦ ЕСЛИ  взять данные из кэша

    ЕСЛИ нет данных в кэше перемешать массив положить данные в кэш КОНЕЦ ЕСЛИ взять данные из кэша

    Перемешивай массив с помощью shuffle, он использует какой то свой сид, который при запуске php сбрасывается, т.е. каждый раз одинаково

    либо поищи реализации на основе php-шного mt_rand и сидируй его mt_srand (тебе будет достаточно хранить сид, чтобы уникально перемешивать)

    Как рандомизировать массив с сохранением рандомного порядка?

    <?php  $array = [     1,2,3,4,5     ];  $seed = 11111;  srand($seed);  $shuffled_array = $array; shuffle($shuffled_array); srand();  var_dump($shuffled_array);

    <?php $array = [ 1,2,3,4,5 ]; $seed = 11111; srand($seed); $shuffled_array = $array; shuffle($shuffled_array); srand(); var_dump($shuffled_array);

    для одного и того же $seed будете получать один и тот же результат после shuffle()
    дальше только вопрос для каждого сайта инициализировать уникальный $seed и иметь возможность его поменять или сбросить на другое значение если потребуется получить новый результат перемешивания на сайте

    • Ну да, можно например взять доменное имя сайта, преобразовать его в число и задать seed

    Ответы:

    В итоге я решил перемешивать массив один раз, и сохранять потом в базу уже перемешанный массив, так как это ACF сделал вот так

    function shuffle_assoc($list) {    // Взял вот тут https://qna.habr.com/q/1006513     if (!is_array($list)) { 		return $list;     }      $keys = array_keys($list);     shuffle($keys);     $random = [];     foreach ($keys as $key) { 		$random[$key] = $list[$key]; 	}   	return $random; }  function reset_testimonials() { 	$source = get_field('test_repeater',  'options'); 	$new_order = shuffle_assoc($source); 	update_field( 'test_repeater',  $new_order,  'options' ); 	wp_die();	 }

    function shuffle_assoc($list) { // Взял вот тут https://qna.habr.com/q/1006513 if (!is_array($list)) { return $list; } $keys = array_keys($list); shuffle($keys); $random = []; foreach ($keys as $key) { $random[$key] = $list[$key]; } return $random; } function reset_testimonials() { $source = get_field('test_repeater', 'options'); $new_order = shuffle_assoc($source); update_field( 'test_repeater', $new_order, 'options' ); wp_die(); }

    Ну и вывел в админке кнопку которая по AJAX вызывает reset_testimonials и сохраняет новый порядок значений.

    Я просто пол дня провел пытаясь решить проблему на выводе беря исходную последовательность и преобразовывая порядок перед выдачей. Но тогда все равно надо как то генерировать и сохранять массив для сортировки и потом с помощью array_multisort выводить значения первого массива по порядку второго. Оказалось проще правда один раз перемешать и сохранить новый порядок в том же виде. Все работает. Всем спасибо за участие. Но я зря создал этот вопрос, в итоге решил все немного изменив подход к задаче.

    Нужно решить такую задачу?

    Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

    Заказать помощь
    Лучший ответ
    1
    Алексей Денисов Ответ

    Вам нужен не случайный порядок при каждом запросе, а детерминированное перемешивание: один раз сгенерировать порядок для конкретной копии сайта и дальше использовать его постоянно. Для WordPress это можно хранить в option, transient без истечения или в отдельном meta-поле, если массив относится к записи.

    Пример для ACF repeater: берём массив, проверяем сохранённый порядок, если его нет — создаём и сохраняем.

    $rows = get_field('items_repeater', 'option');
     
    if (!is_array($rows)) {
        return;
    }
     
    $order = get_option('my_items_random_order');
     
    if (!is_array($order) || count($order) !== count($rows)) {
        $order = array_keys($rows);
        shuffle($order);
        update_option('my_items_random_order', $order, false);
    }
     
    foreach ($order as $index) {
        if (!isset($rows[$index])) {
            continue;
        }
     
        $row = $rows[$index];
        // Выводите элемент.
    }

    $rows = get_field('items_repeater', 'option'); if (!is_array($rows)) { return; } $order = get_option('my_items_random_order'); if (!is_array($order) || count($order) !== count($rows)) { $order = array_keys($rows); shuffle($order); update_option('my_items_random_order', $order, false); } foreach ($order as $index) { if (!isset($rows[$index])) { continue; } $row = $rows[$index]; // Выводите элемент. }

    Если сайтов-копий много и нужно, чтобы порядок отличался автоматически, можно сделать seed от домена. Но встроенный shuffle() не принимает seed, поэтому проще сохранить порядок при первом запуске. Тогда каждая копия сама создаст свой вариант и больше его не поменяет.

    Важно предусмотреть изменение массива. Если добавились новые элементы, старый порядок можно сохранить, а новые индексы добавить в конец или перемешать только новые. Если удалить элемент, нужно отфильтровать отсутствующие индексы. Иначе при изменении repeater порядок начнёт ломаться или часть элементов исчезнет.

    Другие ответы (0)

    Пока нет других ответов. Будьте первым, кто поможет автору.

    Ответить на вопрос

    комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *

    Вам также может быть интересно