tags:

views:

467

answers:

7

I know how to select one random item from an array, but how about ten random items from an array of, say, twenty items? (In PHP.)

What makes it a little more complicated is that each item actually has two parts: a filename, and a description. Basically, it's for a webpage that will display ten random images each time you reload. The actual format of this data doesn't really matter, although it's simple enough that I'd prefer to contain it in flat-text or even hard code it rather than set up a database. (It's also not meant to change often.)

Bonus question, not sure if I'm going to do this just yet - but how would you weight the entries, such that certain items always get picked, or at least more frequently than others?

Thanks.

+10  A: 

How to select one or more random items from an array in php: http://us3.php.net/manual/en/function.array-rand.php

How to do random weighted elements:
http://20bits.com/articles/random-weighted-elements-in-php/

Mr. Smith
I didn't know array_rand could select more than one entry out of an array, but that worked great for me.
saikofish
A: 
<?php
$inarray = range(0,100);
shuffle($inarray);
$outarray = array_slice($inarray, 0, 20);
?>
+10  A: 

You could shuffle the array and then pick the first ten elements with array_slice:

shuffle($array);
$tenRandomElements = array_slice($array, 0, 10);
Gumbo
A: 

An array of arrays in PHP should be a good strategy. You can keep the data for these array in any way you like (hard-coded, XML, etc) and arrange it in the arrays as such:

Array {
    Array (item0) { filename,description, weight,...}
    Array (item1) { filename,description, weight,...}
    Array (item2) { filename,description, weight,...} 
}

You can then use the array_rand function to randomly remove items from the array. Creating a weight value for each entry will allow you to pick one entry over another using some sort of priority strategy (e.g. randomly get 2 items from the array, check weight, pick the one with a greater weight and replace the other)

shambleh
+2  A: 

Example #1 array_rand() example

<?php
$input = array("Neo", "Morpheus", "Trinity", "Cypher", "Tank");
$rand_keys = array_rand($input, 2);
echo $input[$rand_keys[0]] . "\n";
echo $input[$rand_keys[1]] . "\n";
?>
Celeron
A: 

Bonus question answer: Take a look at Roulette Wheel selection. The website talks about geentic algorithms, but the selection methods are sound and can be applied to a range of ideas.

DanDan
A: 

I have some code that sort of does what you ask for. I store a list of sponsorship links in a text file, and pick them at random. But, if I want to skew the set, I use multiple the links ;-)

Sponsors file:

<a href="http://www.example.com"&gt;Example&lt;/a&gt;
<a href="http://www.example.com"&gt;Example&lt;/a&gt;
<a href="http://www.bbc.co.uk"&gt;BBC&lt;/a&gt;
<a href="http://www.google.com"&gt;Google&lt;/a&gt;

PHP:

$sponsor_config = 'sponsors.txt';
$trimmed = file($sponsor_config, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$op = array();

$limit = 20; // insurance
$loops = 0;
$needed =  4;
$op[] = '<div id="sponsorship"><!-- start sponsorship -->';
$selected = array();
while ( (count($selected) < $needed) AND ($loops <= $limit)) {
  $choice = rand(0, count($sponsors)-1);
  if(!in_array($sponsors[$choice], $selected)) $selected[] = $sponsors[$choice];
  $loops++;
}

foreach($selected as $k => $selection) {
  $op[] = '<p class="sponsorship bg_'.($k%3+1).'">Click the link below to<br />visit our Site Sponsor:<br />'.$selection.'</p>';
}

$op[] = '</div><!-- end sponsorship -->';
return join("\n",$op)."\n";

V. quick and v.v. dirty... but it works

Dycey
Thanks for all the help everyone. I've decided, for now, that rather than use a weighting scheme, the ones I want to appear all the time will just not be entered into the array, and the ones that will appear randomly will be chosen out of the array.
saikofish