从数组中随机选择元素,然后将其从数组中移除。

20
我有一个短语数组。我想在循环中随机选择数组中的短语。 我不想在循环中多次选择相同的短语。 我认为我可以在随机选择短语后在下一个循环之前将其删除。

http://codepad.org/11l0nStX

<?php
for ($i=0; $i<16; $i++) {
    $phrases = array(
        'Hello Sailor', 'Acid Test', 'Bear Garden', 'Botch A Job',
        'Dark Horse', 'In The Red', 'Man Up', 'Pan Out',
        'Quid Pro Quo', 'Rub It In', 'Turncoat', 'Yes Man',
        'All Wet', 'Bag Lady', 'Bean Feast', 'Big Wig',
    );

    $ran_Num = array_rand($phrases);
    $ran_Phrase = $phrases[$ran_Num];
    unset($phrases[$ran_Phrase]);
    echo $ran_Phrase . "\r\n";
    echo count($phrases) . "\r\n";
}

在每次循环中随机选择不同的短语是否可能从数组中选择?


使用类似于array_pop的函数,它会弹出并返回数组的最后一个值,并将数组长度减少一个元素。 - andrew-caulfield
以上代码的实际错误是由于数组包含在循环内部。每次迭代时,它都会被重置。我没有测试过,但这是显而易见的。 - ArtisticPhoenix
6个回答

45

将数组随机打乱顺序,然后只弹出最后一个元素。

$array = [...];

shuffle($array);

while($element = array_pop($array)){
  echo 'Random element:' . $element;
}

1
我喜欢这种方法,简单而干净。唯一的问题是你最终得到了一个洗牌后的数组,所以这并不涵盖所有的用例。 - Vladimir Hraban

4
您也可以使用array_slice函数。
$ran_Num = array_rand($phrases);
$ran_Phrase = array_slice($phrases, $ran_Num, 1);

你如何确保你删除的是所选的那一个? - UnixAgain
2
doc 中: "返回切片。" - Toto
抱歉我误解了。array_rand()返回的是索引数组的索引,而不是该索引处的值。 - UnixAgain
这是我认为更好的解决方案。请注意,它返回一个数组,因此您需要该数组的第一个元素。 - winkbrace

1

这个问题有点老了,但是一个简单的解决方案就是随机获取数组的一个键,然后将其删除。

  <?php
    $phrases = array('Hello Sailor','Acid Test','Bear Garden','Botch A Job','Dark Horse',
    'In The Red','Man Up','Pan Out','Quid Pro Quo','Rub It In','Turncoat',
    'Yes Man','All Wet','Bag Lady','Bean Feast','Big Wig');

  $ran_Num = array_rand(array_keys($phrases));
  $ran_Phrase = $phrases[$ran_Num];
  unset($phrases[$ran_Phrase]);
  echo $ran_Phrase . "\r\n";
  echo count($phrases) . "\r\n";

1

你也可以使用array_rand和array_splice

$array = array('Hello Sailor','Acid Test','Bear Garden','Botch A Job','Dark Horse',
                'In The Red','Man Up','Pan Out','Quid Pro Quo','Rub It In','Turncoat',
                'Yes Man','All Wet','Bag Lady','Bean Feast','Big Wig');

$el = array_rand($array);
$dat = $array[$el];
array_splice($array, $el, 1 );

0
将所选值放入一个新数组中,然后检查它是否存在于新数组中,如果不存在,则添加进去。
<?php
$phrases = array('Hello Sailor','Acid Test','Bear Garden','Botch A Job','Dark Horse',
    'In The Red','Man Up','Pan Out','Quid Pro Quo','Rub It In','Turncoat',
    'Yes Man','All Wet','Bag Lady','Bean Feast','Big Wig');

$default = 16;
if($default > ($c = count($phrases))) $default = $c;

$keys = array_rand($phrases, $default);

$newPhrases = array();
foreach($keys as $key){
    if(!isset($newPhrases[$key])){
        $newPhrases[$key] = $phrases[$key];
    }
}
print_r($newPhrases);

еңЁеҫӘзҺҜдёӯдҪҝз”Ёin_arrayе’Ңarray_randжҳҜдёҖдёӘдёҚеҘҪзҡ„дё»ж„ҸгҖӮ - Mārtiņš Briedis
我喜欢你的方式更好。但这只是一个选项。 - Get Off My Lawn
你可以尝试改进 - 在开始时使用 array_flip,然后像这样搜索:if(isset($phrases[$phrase]))。这样会更快,特别是在循环中 :) - Mārtiņš Briedis

0

这里的其他答案都可行,但我想着眼于您的代码。

<?php

我将$phrases的定义从循环外部提取出来。将其设置在循环内部会导致每次重置,这是不好的。

$phrases = array('Hello Sailor','Acid Test','Bear Garden','Botch A Job','Dark Horse',
        'In The Red','Man Up','Pan Out','Quid Pro Quo','Rub It In','Turncoat',
         'Yes Man','All Wet','Bag Lady','Bean Feast','Big Wig');

我不喜欢数数,所以我让电脑来做。

for($i=0,$n=count($phrases); $i<$n; $i++){

    $ran_Num = array_rand($phrases);
    $ran_Phrase = $phrases[$ran_Num];

当你要对一个数组进行解除设置操作时,方括号内的值应该是你想要删除的数组元素的索引,而不是元素值本身。方括号内的变量名已经从$ran_Phrase更改为ran_Num

    unset($phrases[$ran_Num]);
    echo $ran_Phrase."\r\n";
    echo count($phrases)."\r\n";
}
?>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接