in reply to Choose random element of array?

Or, if you want "pick once" functionality (consumes the original array):
my $color = splice(@colors, rand @colors, 1);

Cheers,
Matt

Replies are listed 'Best First'.
Re: Re: Choose random element of array?
by hsinclai (Deacon) on May 28, 2004 at 16:50 UTC
    As mojotoad points out, when you need that "pick once" functionality from the array, splice() works wonders.. (in the example below, the @testarray has 1052 elements, so the counter runs out at 1051:)

    use strict; my $counter = 0; my $randstring; my @testarray = ( 'a' .. 'z', 'A' .. 'Z', '0' .. '999' ); do { $randstring .= splice(@testarray, int rand @testarray, 1); ++$counter; } until $counter == 1051; print "$randstring\n";


      Nice snippet. I couldn't help but point out that you already have a built-in counter -- the number of elements in the array. Reworking your example a bit, we get the following:
      use strict; my $randstring; my @testarray = ( 'a' .. 'z', 'A' .. 'Z', '0' .. '999' ); $randstring .= splice(@testarray, rand @testarray, 1) while @testarray; print "$randstring\n";
      Cheers,
      Matt

        That's definitely better -thanks!

      What you have there is essentially a shuffle and join. Using splice to shuffle is tempting, but inefficient. perlfaq4 already covers this topic well, and List::Util's shuffle makes it convenient.

        Thanks for these pointers, it will take me to the next level of understanding this stuff..

        Now, at what point, do you do the Fisher-Yates thing in your code.. when you've got a larger array to deal with I guess - but how large?

        Tried looking to see if List::Util uses a Fisher-Yates but it seems to be a .so binary, a library.

        You do realize, that now, I will not ever be able to type the word "splice" without severe pangs of guilt and inefficiency...