2016-07-05 106 views
3

我有一个布尔值数组,我想从中选择一个随机索引,其值为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()函数,我可以给出一个先决条件?

+0

你打算在一个循环或类似的东西运行此那会在一个点上做每个“真实”的入口? –

回答

2
$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指标之一为假,你应该:

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

循环这两条线将最终将所有指标为false:

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

您可以使用下面的代码:

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

$randTrueIndex = array_rand(array_filter($arr, function($item) { 
    return $item; 
})); 

$arr[$randTrueIndex] = false; 
0

做到不浪费任何工作将是创建数组索引的随机排列的最简单方法。 Knuth shuffle(也被称为Fisher-Yates shuffle)应该令人赞叹。

某些应用的另一种选择是挑选一个发生器,该发生器创建所需范围内的值而不重复,或仅具有相对较少数量的异常值(超出目标范围的值)。例如,所有linear-congruential generators都具有任何较低的n位循环周期为2^n的属性。选择两个不小于数组大小的第一个幂数,并且平均每个好的数字都会产生少于一个的浪费数。

+1

我想过排列组合。但是由于这个数组在开始时并不完全正确,似乎没有办法预先选择真正的索引。 感谢您提到发电机。我牢记在心。 – Sebastian

+0

@Sebastian:在这种情况下,你可以选择真正的条目索引到一个数组中,然后洗牌...即,基本上Ismail写的是什么。 – DarthGizka