PHP Random Shuffle Array Maintaining Key => Value

PhpArrays

Php Problem Overview


I've been looking on google for the answer but can't seem to find something fool-proof and cant really afford to mess this up (going live into a production site).

What I have is an advanced search with 20+ filters, which returns an array including an ID and a Distance. What I need to do is shuffle these results to display in a random order every time. The array I have that comes out at the moment is:

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 )
)

What I need to be able to do is randomise or order of these every time but maintain the id and distance pairs, i.e.:

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 )
)

Thanks :)

Php Solutions


Solution 1 - Php

The first user post under the shuffle documentation:

> Shuffle associative and > non-associative array while preserving > key, value pairs. Also returns the > shuffled array instead of shuffling it > in place.

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; 
} 

Test case:

$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));

Solution 2 - Php

As of 5.3.0 you could do:

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

Solution 3 - Php

Take a look to this function here :

     $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);

Original post here : http://us3.php.net/manual/en/function.shuffle.php#83007

Solution 4 - Php

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

Solution 5 - Php

I was having a hard time with most of the answers provided - so I created this little snippet that took my arrays and randomized them while maintaining their keys:

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

Solution 6 - Php

Charles Iliya Krempeaux has a nice writeup on the issue and a function that worked really well for me:

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


    // Get array's 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;
}

Solution 7 - Php

Try using the fisher-yates algorithm from here:

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; 
} 

I had to implement something similar to this for my undergraduate senior thesis, and it works very well.

Solution 8 - Php

Answer using shuffle always return the same order. Here is one using random_int() where the order is different each time it is used:

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;
}

Solution 9 - Php

  $testArray = array('a' => 'apple', 'b' => 'ball', 'c' => 'cat', 'd' => 'dog');
  $keys = array_keys($testArray); //Get the Keys of the array -> a, b, c, d
  shuffle($keys); //Shuffle The keys array -> d, a, c, b
  $shuffledArray = array();
  foreach($keys as $key) {
    $shuffledArray[$key] = $testArray[$key]; //Get the original array using keys from shuffled array
  }
  print_r($shuffledArray);
  /*
  Array
  (
      [d] => dog
      [a] => apple
      [c] => cat
      [b] => ball
  )
  */

Solution 10 - Php

I tried the most vote solution didn't popular shuffle list. This is the change I made to make it work. I want my array key starting from 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;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionlethalMangoView Question on Stackoverflow
Solution 1 - Phpkarim79View Answer on Stackoverflow
Solution 2 - PhpHamishView Answer on Stackoverflow
Solution 3 - Phpv1r00zView Answer on Stackoverflow
Solution 4 - PhpJake WilsonView Answer on Stackoverflow
Solution 5 - PhpchaudrucView Answer on Stackoverflow
Solution 6 - PhpcwdView Answer on Stackoverflow
Solution 7 - PhpJesseBueskingView Answer on Stackoverflow
Solution 8 - PhpGautierView Answer on Stackoverflow
Solution 9 - PhpDavid CorpView Answer on Stackoverflow
Solution 10 - PhpTom KimView Answer on Stackoverflow