2

In my php script, I have a variable $data that contains an array that may have various number of elements.

The script picks one of the array elements at random and outputs it to the browser:

# count number of elements in $data
$n = count($data);

# pick a random number out of the number of elements in $data
$rand = rand(0, ($n - 1));

# output a random element
echo '<p> . trim($data[$rand]) . '</p>';

QUESTION: I want to improve that script, so that it doesn't output the same array element again until it runs out of array elements. For example, if an array contains elements numbered 0 to 9, and the script picked an array element #4, I want it to remember that, and next time the script runs, to exclude the element that was #4.

It could probably be done in many different ways, but I'm looking for the simplest and most elegant solution, and would be grateful for help from a PHP expert.

4 Answers 4

2

Save the numbers that were already picked in the user's session.

session_start();
$n = count($data); 

// If the array isn't initialized, or we used all the numbers, reset the array
if( !isset( $_SESSION['used_nums']) || count( $_SESSION['used_nums']) == $n) {
    $_SESSION['used_nums'] = array();
}

do{ 
    $rand = rand(0, ($n - 1));
} while( isset( $_SESSION['used_nums'][$rand]));

echo '<p>' . trim($data[$rand]) . '</p>';    
$_SESSION['used_nums'][$rand] = 1;

Or, perhaps a more clever way, using array_intersect_key and array_rand:

session_start();
$n = count($data); 

// If the array isn't initialized, or we used all the numbers, reset the array
if( !isset( $_SESSION['used_nums']) || count( $_SESSION['used_nums']) == $n) {
    $_SESSION['used_nums'] = array();
}

$unused = array_intersect_key( $data, $_SESSION['used_nums'];
$rand = array_rand( $unused);

echo '<p>' . trim($unused[$rand]) . '</p>';    
$_SESSION['used_nums'][$rand] = 1;
Sign up to request clarification or add additional context in comments.

1 Comment

For the second example, you would need to echo trim($unused[$rand])
2

You could shuffle the array and then simply iterate over it:

shuffle($data);
foreach ($data as $elem) {
    // …
}

If you don’t want to alter the array order, you could simply shuffle the array’s keys:

$keys = array_keys($data);
shuffle($keys);
foreach ($keys as $key) {
    // $data[$key]
}

7 Comments

This still leaves the possibility of having the same index twice.
@AustinBrunkhorst Why do you think so?
Because OP wants a random, unique index selected each page load.
Probably there's a way not only to shuffle the order, but also unset the one that has been chosen? Would that work?
@DimitriVorontzov You could do the same with the shuffled array keys, store it in a more persistent storage, and remove the key from the array when displayed.
|
1

You can use sessions to store the indexes you've used so far. Try this.

session_start();

$used = &$_SESSION['usedIndexes'];

// used all of our array indexes
if(count($used) > count($data)) 
    $used = array();

// remove the used indexes from data
foreach($used as $index)
    unset($data[$index]);

$random = array_rand($data);

// append our new index to used indexes
$used[] = $random;

echo '<p>', trim($data[$random]) ,'</p>';

Comments

0
$selection=$x[$randomNumber];
unset($x[$randomNumber]);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.