2016-07-05 98 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