PHP 随机洗牌数组维护键 => 值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4102777/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 11:57:36  来源:igfitidea点击:

PHP Random Shuffle Array Maintaining Key => Value

phparrays

提问by lethalMango

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

我一直在 google 上寻找答案,但似乎无法找到一些万无一失的东西,并且无法真正搞砸(进入生产站点)。

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:

我拥有的是带有 20 多个过滤器的高级搜索,它返回一个包含 ID 和距离的数组。我需要做的是随机排列这些结果,每次都以随机顺序显示。我现在出来的数组是:

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.:

我需要能够做的是每次随机化或排序这些,但保持 id 和距离对,即:

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

谢谢 :)

回答by karim79

The first user postunder the shuffledocumentation:

第一个用户后shuffle的文件:

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

回答by Hamish

As of 5.3.0 you could do:

从 5.3.0 开始,您可以执行以下操作:

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

回答by v1r00z

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

原帖在这里:http: //us3.php.net/manual/en/function.shuffle.php#83007

回答by Jake Wilson

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

回答by chaudruc

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

回答by JesseBuesking

Try using the fisher-yates algorithm from here:

尝试使用此处的 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; 
} 

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

我不得不为我的本科毕业论文实现类似的东西,而且效果很好。

回答by cwd

Charles Iliya Krempeauxhas a nice writeupon the issue and a function that worked really well for me:

Charles Iliya Krempeaux一篇关于这个问题的好文章和一个对我来说非常有效的函数:

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

回答by Tom Kim

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.

我尝试了最多投票的解决方案没有流行的洗牌列表。这是我为使其工作所做的更改。我希望我的数组键从 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;
}

回答by Gautier

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

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