【问题标题】:Choose random index of array with condition on value选择具有条件值的数组的随机索引
【发布时间】:2016-11-06 19:45:45
【问题描述】:

我有一个布尔数组,我想从中选择一个值为 true 的随机索引并将其设置为 false。

当然,我可以通过选择索引来蛮力做到这一点,直到我找到一个值为 true 的索引:

$arr = array(true, false, false, true, false, true);

var_dump($arr);

$i = array_rand($arr);
while(!$arr[$i])
{
    $i = array_rand($arr);
}
$arr[$i] = false;

var_dump($arr);

这将创建类似这样的内容,其中第四个条目已更改。

array(6) {
  [0]=>
  bool(true)
  [1]=>
  bool(false)
  [2]=>
  bool(false)
  [3]=>
  bool(true)
  [4]=>
  bool(false)
  [5]=>
  bool(true)
}

array(6) {
  [0]=>
  bool(true)
  [1]=>
  bool(false)
  [2]=>
  bool(false)
  [3]=>
  bool(false)
  [4]=>
  bool(false)
  [5]=>
  bool(true)
}

但是,我必须使用一个明显更大的数组多次执行此操作。在某些时候,数组几乎是完全错误的,在这种情况下,蛮力方法相当低效。

有没有更优雅的方法来解决这个问题?任何一种array_rand() 函数,我可以在哪里给出前提条件?

【问题讨论】:

  • 您是否打算在循环中运行它或类似的东西会在某一时刻执行每个 true 条目?

标签: php arrays random conditional-statements


【解决方案1】:
$arr = array(true,true,false,false,true,false);

$res = array_keys($arr, true);

var_dump($res);  // returns 0,1,4

echo $res[array_rand($res)]; //echo one of the indexes that is true

以上代码返回$res中$arr的真实值的索引。

https://3v4l.org/CG1v2

编辑。然后将 $arr 索引之一设置为 false,您应该:

$arr[$res[array_rand($res)]] = false; // will set one as false.

循环这两行最终会将所有索引设置为false:

$res = array_keys($arr, true);
$arr[$res[array_rand($res)]] = false;

【讨论】:

    【解决方案2】:

    不浪费任何工作的最简单方法是创建数组索引的随机排列。 Knuth shuffle(也称为Fisher-Yates shuffle)应该可以很好地工作。

    对于某些应用程序的另一个选项是选择一个生成器,该生成器可以在不重复的情况下创建所需范围内的值,或者只有相对少量的异常值(超出目标范围的值)。例如,所有linear-congruential generators 都具有任何低 n 位以周期 2^n 循环的属性。选择不小于您的数组大小的 2 的第一个幂,您将平均为每个好的数字生成少于一个浪费的数字。

    【讨论】:

    • 我想到了排列。但由于数组一开始并不完全正确,似乎没有办法先预选真正的索引。感谢您提及生成器。我牢记在心。
    • @Sebastian:在这种情况下,您可以将真实条目的索引选择到一个数组中并将其打乱......即基本上是伊斯梅尔写的。
    【解决方案3】:

    您可以使用以下代码:

    $arr = array(true, false, false, true, false, true);
    
    $randTrueIndex = array_rand(array_filter($arr, function($item) { 
        return $item;
    }));
    
    $arr[$randTrueIndex] = false;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-21
      • 1970-01-01
      • 1970-01-01
      • 2016-03-21
      • 2021-07-03
      • 2020-10-27
      相关资源
      最近更新 更多