Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

Re: rand + shift || pop

by kennethk (Abbot)
on Dec 21, 2010 at 15:28 UTC ( [id://878288] : note . print w/replies, xml ) Need Help??

in reply to rand + shift || pop

In addition to the lovely splice-based approaches listed above, if you are simply using your array as a grab-bag and have no need to maintain order, combining shuffle from List::Util (core) with pop or shift should yield a cleaner solution:

#!/usr/bin/perl use strict; use warnings; use List::Util qw (shuffle); my @array = (0 .. 9); @array = shuffle @array; print pop(@array), "\n", @array;

Note this is discussed in perlfaq4's How do I shuffle an array randomly?.

Replies are listed 'Best First'.
Re^2: rand + shift || pop
by magnus (Pilgrim) on Dec 21, 2010 at 15:32 UTC
    While splice is helpful, shuffle + shift || pop is a very simple and elegant solution. Didn't even twig on that one. Thanks very much.
      Shuffleing is O(n) and spliceing is O(1), this may matter if your array is large.

      Update: Oops, my understanding of splice was wrong. See JavaFan and ikegami below.

        Actually, the expected running time of splicing is Ω(n), as a random splice will have to move n/4 elements on average.

        If you want to repeatedly get a random element (without duplication), shuffle the array and use pop or shift, for a linear running time. Repeatedly splicing a random element has an expected running time of Ω(n2).

        It's only O(1) if you remove from the start or the end.
Re^2: rand + shift || pop
by davies (Prior) on Dec 22, 2010 at 15:54 UTC