in reply to Picking unique element in random from a array

Shuffle the array (using "shuffle" from List::Util) and take the first ten elements.

Update: Here's a non-destructive approach that uses "shuffle":

use List::Util 'shuffle'; my @arr = (1 .. 200); my @random = @arr[(shuffle 0 .. $#arr)[0 .. 9]]; print "@random\n";
--
<http://dave.org.uk>

"The first rule of Perl club is you do not talk about Perl club."
-- Chip Salzenberg

Replies are listed 'Best First'.
Re^2: Picking unique element in random from a array
by Limbic~Region (Chancellor) on Aug 09, 2006 at 12:59 UTC
    davorg,
    Great advice and I upvoted you. It is nice to point out though that this, and randomly splicing elements of the original array do not leave it intact. Apparently Data::Random can do this as well as my suggestion of using a parallel array of indices.

    Update: After looking at the source of Data::Random's rand_set(), I noticed the routine can be terribly run-time inefficient depending on the parameters. It continously selects random indices until it finds enough unique ones to satisfy the 'size' option. This is doing a lot more work than necessary. I have emailed the author with suggestions.

    Cheers - L~R

Re^2: Picking unique element in random from a array (partial)
by tye (Sage) on Aug 09, 2006 at 16:50 UTC

    Shuffling all 100 elements (or indices) just to get 10 of them... A partial Fisher-Yates shuffle can be more efficient. For example, using pickFromRange which I wrote after Limbic~Region asked for such a thing in the CB (probably prompted by this thread), you could do:

    my @pick= @quest[ pickFromRange( 10, 0, $#quest ) ];

    Though I bet it will actually be slower than just shuffling the whole list of indices for this particular case given how slow dispatching Perl opnodes is and that List::Util uses XS. But for larger lists, it could be a win.

    - tye