1

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)?

8
  • 1
    "what's the best way to do what I want to achieve?" What's that? Commented Jan 13, 2012 at 14:20
  • 2
    @outis From the question "I want to return 6 random elements as a string (eg. 1a3564):" Commented Jan 13, 2012 at 14:22
  • @Michael: that's not the overarching goal. Did you read the linked page? Commented Jan 13, 2012 at 14:33
  • 1
    @outis: how can i randomly generate a Hex color string :-) Commented Jan 13, 2012 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. Commented Jan 13, 2012 at 15:11

7 Answers 7

5

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

Sign up to request clarification or add additional context in comments.

Comments

5

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.

Comments

3

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?

Comments

2

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);

2 Comments

Shuffle won't return repeated values.
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.
2

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));

3 Comments

Shuffle won't return repeated values.
@jjmontes Excellent point, but neither will array_rand() which is what he was initially using, nor did he say it was a requirement
Indeed. Thanks for taking the time to explain that.
2

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.

1 Comment

Note that there is no guarantee that this method has the same probability for every colour.
1

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);

3 Comments

php.net/manual/en/function.array-rand.php - as of PHP 4.2.0, The random number generator is seeded automatically.
Thanks Timur, updating the answer as per your comment.
array_shuffle() isn't a function. shuffle(), however, is.

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.