Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have an array, such like:

$hex = array("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f");

I want to return 6 random elements as a string (eg. 1a3564):

$random_color = array_rand($hex,6);

I thought imploding $random_color would do the trick:

echo implode($random_color);

But array_rand() stores positions of elements in parent array, not this array elements, so I get something like:

259111213 instead of 259bcd.

I know this does exactly what I want:

echo $hex[$random_color[0]];
echo $hex[$random_color[1]];
echo $hex[$random_color[2]];
echo $hex[$random_color[3]];
echo $hex[$random_color[4]];
echo $hex[$random_color[5]];

But:

  • is there any way to store array elements within array_rand()? Why it stores elements' positions instead of elements in the first place?

  • what's the best way to do what I want to achieve?

  • why does array_rand() NEVER choose a letter as the first element, and almost never as the second/third (99% of generated colors look like 11111a 12345c 123456)?

share|improve this question
1  
"what's the best way to do what I want to achieve?" What's that? –  outis Jan 13 '12 at 14:20
2  
@outis From the question "I want to return 6 random elements as a string (eg. 1a3564):" –  Michael Mior Jan 13 '12 at 14:22
 
@Michael: that's not the overarching goal. Did you read the linked page? –  outis Jan 13 '12 at 14:33
1  
@outis: how can i randomly generate a Hex color string :-) –  Rufinus Jan 13 '12 at 15:06
 
@Rufinus: there's still some things left out. For example, why can't there be repetitions of digits? Knowing the overall goal (what the colors are actually used for) would help quit e abit. –  outis Jan 13 '12 at 15:11
show 3 more comments

7 Answers

up vote 2 down vote accepted

you are close try this:

$hex = array("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f");
shuffle($hex);

echo sub_str(implode('',$hex),0,6);
share|improve this answer
 
Shuffle won't return repeated values. –  jjmontes Jan 13 '12 at 15:06
 
i know, but to be honest it wasnt part of the question. the real question would be "how to generate hex colors randomly" anyway, to which @Timur gave the correct answer. –  Rufinus Jan 13 '12 at 15:08
add comment

Random colors should be generated in simplier way:

printf('%02x%02x%02x',mt_rand(0,255),mt_rand(0,255),mt_rand(0,255));

or

printf('%06x',mt_rand(0,16777215));

If you need to save color to variable, use sprintf instead of printf

share|improve this answer
1  
good eye for detail, i overread the $random_color naming :-) –  Rufinus Jan 13 '12 at 14:33
add comment

Since the items are all different, you can turn them into keys rather than values, then use array_rand on the result:

implode('', array_rand(array_flip($hex), 6));

However, there may be a better way of achieving your overall goal. For example, if the overall goal allows for repetitions of digits, simply generate a random number from 0 through 0xFFFFFF and convert to a hex string:

dechex(mt_rand(0, 0xFFFFFF));
  1. Why it stores elements' positions instead of elements in the first place?

    From the manual page:

    This is done so that you can pick random keys as well as values out of the array.

  2. why does array_rand() NEVER choose a letter as the first element, and almost never as the second/third (99% of generated colors look like 11111a 12345c 123456)?

    array_rand uses rand (php_rand, in the C source). Depending on your system, php_rand is rand, random or lrand48. rand is a particularly poor random number generator.

share|improve this answer
add comment

array_rand() returns the keys of the randomly picked elements (see manual, section Return Values).

In order for it to work as expected, use array_flip() to retrieve the keys:

$random_color = array_rand(array_flip($hex), 6);

As for the "strange" results where there are almost no letters first elements, IDEOne and my server seem to reproduce these findings. A local machine running in my office (still running Debian etch / PHP 5.2.9) seems to disagree and evenly distribute elements from $hex... Seems to be a PHP version thing?

share|improve this answer
add comment

If you don't need to maintain the order of the $hex array, you could substitute this with shuffle(). Something like this (codepad example):

<?php
$hex = array("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f");
shuffle($hex);
echo implode(array_slice($hex, 0, 6));
share|improve this answer
 
Shuffle won't return repeated values. –  jjmontes Jan 13 '12 at 15:07
 
@jjmontes Excellent point, but neither will array_rand() which is what he was initially using, nor did he say it was a requirement –  jprofitt Jan 13 '12 at 15:22
 
Indeed. Thanks for taking the time to explain that. –  jjmontes Jan 13 '12 at 15:29
add comment

If you just want a random string of hex digits, you could also do something like

substr(md5(time()),-6);

or

substr(md5(uniqid()),-6);

You would get similar results without having to mess with the array.

share|improve this answer
 
Note that there is no guarantee that this method has the same probability for every colour. –  jjmontes Jan 13 '12 at 15:09
add comment

is there any way to store array elements within array_rand()? Why it stores elements' positions instead of elements in the first place?

According to array_rand documentation, it returns the array 'keys', not the 'values'. Since your array is not an associative array, the keys are numbers. You'd need to do (untested):

$result = "";
$random_color = array_rand($hex, 6);
foreach ($random_color as $randomIndex) {
  $result = $result . $hex[$randomIndex];
}

Don't use array shuffle or array_rand because elements cannot repeat with that approach. That's not what you are trying to do.

what's the best way to do what I want to achieve?

If you want to generate a random color, you can use:

$color = '';
while(strlen($c) < 6) {
    $color .= sprintf("%02X", mt_rand(0, 255));
}

why does array_rand() NEVER choose a letter as the first element, and almost never as the second/third (99% of generated colors look like 11111a 12345c 123456)?

You may need to initialize the random numbers generator, but this is just a guess (see Timur's comment to this answer).

mt_srand((double)microtime()*1000000);
share|improve this answer
2  
php.net/manual/en/function.array-rand.php - as of PHP 4.2.0, The random number generator is seeded automatically. –  Timur Jan 13 '12 at 14:40
 
Thanks Timur, updating the answer as per your comment. –  jjmontes Jan 13 '12 at 15:09
1  
array_shuffle() isn't a function. shuffle(), however, is. –  jprofitt Jan 13 '12 at 15:28
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.