PHP Random Shuffle Array Поддержание ключа => Значение

Я искал Google для ответа, но не могу найти что-то безумное и не могу позволить себе испортить это (собирается жить на производственный сайт).

У меня есть расширенный поиск с 20 + фильтрами, который возвращает массив, содержащий идентификатор и расстояние. То, что мне нужно сделать, это перетасовать эти результаты для отображения в случайном порядке каждый раз. Массив, который у меня есть, появляется в данный момент:

Array (
    [0] => Array ( [id] => 1 [distance] => 1.95124994507577 )
    [1] => Array ( [id] => 13 [distance] => 4.75358968511882 )
    [2] => Array ( [id] => 7 [distance] => 33.2223233233323 )
    [3] => Array ( [id] => 21 [distance] => 18.2155453552336 )
    [4] => Array ( [id] => 102 [distance] = 221.2212587899658 )
)

Мне нужно иметь возможность делать это случайным образом или порядок каждого из них, но поддерживать пары id и distance, т.е.

Array (
    [4] => Array ( [id] => 102 [distance] = 221.2212587899658 )
    [1] => Array ( [id] => 13 [distance] => 4.75358968511882 )
    [3] => Array ( [id] => 21 [distance] => 18.2155453552336 )
    [2] => Array ( [id] => 7 [distance] => 33.2223233233323 )
    [0] => Array ( [id] => 1 [distance] => 1.95124994507577 )
)

Спасибо:)

Ответ 1

сообщение первого пользователя в shuffle:

Перемешать ассоциативные и неассоциативный массив при сохранении ключ, пары значений. Также возвращает перетасовать массив, а не перетасовывать его на месте.

function shuffle_assoc($list) { 
  if (!is_array($list)) return $list; 

  $keys = array_keys($list); 
  shuffle($keys); 
  $random = array(); 
  foreach ($keys as $key) { 
    $random[$key] = $list[$key]; 
  }
  return $random; 
} 

Тестовый пример:

$arr = array();
$arr[] = array('id' => 5, 'foo' => 'hello');
$arr[] = array('id' => 7, 'foo' => 'byebye');
$arr[] = array('id' => 9, 'foo' => 'foo');
print_r(shuffle_assoc($arr));
print_r(shuffle_assoc($arr));
print_r(shuffle_assoc($arr));

Ответ 2

Начиная с 5.3.0 вы можете сделать:

uksort($array, function() { return rand() > rand(); });

Ответ 3

Посмотрите на эту функцию здесь:

     $foo = array('A','B','C'); 


function shuffle_with_keys(&$array) {
    /* Auxiliary array to hold the new order */
    $aux = array();
    /* We work with an array of the keys */
    $keys = array_keys($array);
    /* We shuffle the keys */`enter code here`
    shuffle($keys);
    /* We iterate thru' the new order of the keys */
    foreach($keys as $key) {
      /* We insert the key, value pair in its new order */
      $aux[$key] = $array[$key];
      /* We remove the element from the old array to save memory */
      unset($array[$key]);
    }
    /* The auxiliary array with the new order overwrites the old variable */
    $array = $aux;
  }

      shuffle_with_keys($foo);
      var_dump($foo);

Оригинальный пост здесь: http://us3.php.net/manual/en/function.shuffle.php#83007

Ответ 4

Мне было трудно с большей частью предоставленных ответов - поэтому я создал этот маленький фрагмент, который взял мои массивы и рандомизировал их, сохраняя их ключи:

function assoc_array_shuffle($array)
{
    $orig = array_flip($array);
    shuffle($array);
    foreach($array AS $key=>$n)
    {
        $data[$n] = $orig[$n];
    }
    return array_flip($data);
}

Ответ 5

function shuffle_assoc($array)
{
    $keys = array_keys($array);
    shuffle($keys);
    return array_merge(array_flip($keys), $array);
}

Ответ 6

Попробуйте использовать алгоритм fisher-yates из здесь:

function shuffle_me($shuffle_me) { 
   $randomized_keys = array_rand($shuffle_me, count($shuffle_me)); 
   foreach($randomized_keys as $current_key) { 
       $shuffled_me[$current_key] = $shuffle_me[$current_key]; 
   } 
   return $shuffled_me; 
} 

Мне пришлось реализовать что-то похожее на это для моей студентской дипломной работы, и это работает очень хорошо.

Ответ 7

Charles Iliya Krempeaux имеет хорошую запись на проблема и функция, которая очень хорошо работала для меня:

function shuffle_assoc($array)
{
    // Initialize
        $shuffled_array = array();


    // Get array keys and shuffle them.
        $shuffled_keys = array_keys($array);
        shuffle($shuffled_keys);


    // Create same array, but in shuffled order.
        foreach ( $shuffled_keys AS $shuffled_key ) {

            $shuffled_array[  $shuffled_key  ] = $array[  $shuffled_key  ];

        } // foreach


    // Return
        return $shuffled_array;
}

Ответ 8

Я пробовал, что большинство решений для голосования не было популярным списком тасов. Это изменение, которое я сделал, чтобы заставить его работать. Я хочу, чтобы мой ключ массива начинался с 1.

 $list = array_combine(range(1,10),range(100,110));
 $shuffle_list =  shuffle_assoc($list);


function shuffle_assoc($list)
{
    if (!is_array($list)) return $list;

    $keys = array_keys($list);
    shuffle($list);
    $random = array();
    foreach ($keys as $k => $key) {
        $random[$key] = $list[$k];
    }
    return $random;
}

Ответ 9

Ответ с использованием shuffle всегда возвращает один и тот же порядок. Вот пример использования random_int(), где порядок меняется каждый раз, когда он используется:

function shuffle_assoc($array)
{
    while (count($array)) {
        $keys = array_keys($array);
        $index = $keys[random_int(0, count($keys)-1)];
        $array_rand[$index] = $array[$index];
        unset($array[$index]);
    }

    return $array_rand;
}