ev00rg has asked for the wisdom of the Perl Monks concerning the following question:

Is there a way to select multiple values from the array without repetition? For instance how to properly do the following:
my @arr = ('A'..'Z'); my $random_letter1 = $arr[int rand @arr]; my $random_letter2 = $arr[int rand @arr]; my $combo = $random_letter1 . $random_letter2; print $combo . "\n";
Is there a way to do selection of both values in one line instead of adding up random_letter1, 2 and so on?

Replies are listed 'Best First'.
Re: oneliner for selecting multiple values from array
by ccn (Vicar) on Nov 18, 2008 at 13:49 UTC
    my @arr = ('A'..'Z'); my $combo = join '', @arr[rand @arr, rand @arr]; print $combo . "\n";

    see Slices

      Another way using the core module List::Util
      use List::Util qw(shuffle); my @arr = ('A'..'Z'); my $combo = join '', (shuffle(@arr))[0..1]; print "$combo\n";
        Your solution, toolic, is nice but not equivalent to the original script; the original could choose two elements that are equal; yours can't... ;-)
        []s, HTH, Massa (κς,πμ,πλ)

      A little more generally you could:

      my @arr = ('A'..'Z'); my $n = 2 ; my $combo = join '', map { $arr[rand @arr] } (1..$n) ; print $combo . "\n";
      which will give you any length string you like.

      Whatever you do, don't do:

      my @arr = ('A'..'Z'); my $n = 2 ; my $combo = $arr[rand @arr] x $n ; print $combo . "\n";
      however plausible it might appear :-(

      Of course it doesn't work, you say, it's obvious... However, I have, ahem, a friend who once (once was enough):

      my @arr = ([]) x $count ;
      and had a lot of fun (tm) working out why their program behaved as oddly as it did !

      many thanks!
Re: oneliner for selecting multiple values from array
by ig (Vicar) on Nov 18, 2008 at 20:55 UTC

    Or even...

    my @arr = ('A'..'Z'); my $n = 2; my $combo; $combo .= $arr[rand @arr] for (1..$n); print "$combo\n";
Re: oneliner for selecting multiple values from array
by repellent (Priest) on Nov 18, 2008 at 23:41 UTC
    Without repetition:
    my @arr = ('A' .. 'Z'); my @combo; my $n = 2; # keep at it till we get $n random values in one pass do { @combo = (); my $i = 0; rand(1) < $n / ++$i && splice(@combo, rand(@combo), $n <= @combo, +$_) for @arr; } while @combo < $n; print "@combo\n";