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

Hi Everyone, I am hoping someone can help me with a problem that I have spent a day trying to google and make it work for me. Basically i am trying to create a little app to generate a series of images from my photo stash. I have it working on a basic level. However I want to make sure there are no dupe images. All the image locations are are read into an array from a text file. Then I use                             $random_img=int(rand($total_input_lines)); This gives a random number for the image to use from the array of possibles. The only problem it doesn't take into account that there may be several duplications. Is there any simple way to make sure that any image is not repeated? Any help would be appreciated. Stu

Replies are listed 'Best First'.
Re: Unique entries from an array
by AnomalousMonk (Archbishop) on Nov 07, 2009 at 19:43 UTC
    Just  shuffle the array, then take elements in order until the array is exhausted:
    >perl -wMstrict -le "use List::Util qw(shuffle); my @array = 1 .. 10; @array = shuffle @array; my $i = 0; while ($i < @array){ print $array[$i]; ++$i; } " 10 2 3 1 8 9 7 4 5 6
Re: Unique entries from an array
by gmargo (Hermit) on Nov 07, 2009 at 20:02 UTC

    One simple way is to use each filename as the key in a hash.

    my @images; # array of filenames my %img; # hash used temporarily $img{$_} = 1 foreach @images; # stick them in a hash @images = keys %img; # now only unique filenames

    A slightly fancier way using grep that preserves the original order:

    @images = grep { ! $img{$_}++ } @images;

Re: Unique entries from an array
by CountZero (Bishop) on Nov 07, 2009 at 19:44 UTC
    List::MoreUtils has a function uniq that returns a list without duplicates.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Re: Unique entries from an array
by Not_a_Number (Prior) on Nov 07, 2009 at 20:07 UTC
    there may be several duplications...

    Not enough information. Do you mean:

    1 Duplicated names in the array? (eg dad_and_brittney.jpg occurs more than once?). In that case, pre-process your array to exclude such duplicates:

    # Assume @all_pics to be your array my %seen; @all_pics = grep !$seen{$_}++, @all_pics;

    2 You don't want to display a picture that has already been shown?

    my $pic = splice @all_pics, rand @all_pics, 1;

    3 You have duplicate pictures with different names? That's a whole 'nother problem...

Re: Unique entries from an array
by 7stud (Deacon) on Nov 07, 2009 at 22:24 UTC
    All the image locations are are read into an array from a text file.

    Rather that having to rework the values you entered into your array, don't read them into an array in the first place--use a hash instead.

    use strict; use warnings; use 5.010; my %pics; while (<DATA>) { chomp; $pics{$_} = 1; } my @unique_names = keys %pics; foreach (@unique_names) { say; } __DATA__ /a/b/img1.jpg /a/b/img1.jpg /a/b/img2.jpg /x/y/img2.jpg /x/y/img2.jpg /x/y/img3.jpg

    --output:--

    /a/b/img2.jpg /a/b/img1.jpg /x/y/img3.jpg /x/y/img2.jpg