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

I have an array where I print out the values but I really need just the unique values. Please advise how I can get just the unique values in this array?
push(@values, $var); foreach (@values) { print "$_\n"; }

Replies are listed 'Best First'.
Re: Unique values in array
by broquaint (Abbot) on Jun 27, 2003 at 14:51 UTC
    If you don't mind losing order then you can just 'hashify' it e.g
    my @array = qw/ foo bar baz foo quux baz /; print map "$_\n", keys %{ {map {$_ => 1} @array} }; __output__ foo quux baz bar

    HTH

    _________
    broquaint

      Thank you, it now works. If possible can you please explain what is going on in this statement?
      print map "$_\n", keys %{ {map {$_ => 1} @array} };
      I am lost on the keys and map part??
        Alrighty, let's break it down then
        map { $_ => 1 } @array
        For each value in @array apply the transform in the block (denoted by the curly braces), in this case create a two element list consisting of each element of the list and a literal 1, collect the output of those transforms and return them as a list. So the map creates a list of key-value pairs (although the value is superfluous in this case) perfect for a hash ...
        { map { $_ => 1 } @array }
        The extra curly braces around the map statement create an anonymous hash, so all duplicate keys in the list created by map are collapsed in the anonymous hash.
        keys %{ {map {$_ => 1} @array} }
        Dereference the anonymous hash created and return a list of its keys.
        print map "$_\n", keys %{ {map {$_ => 1} @array} };
        The final map then simply a creates a list where each key has a \n appended and then print prints that list.
        HTH

        _________
        broquaint

Re: Unique values in array
by Abigail-II (Bishop) on Jun 27, 2003 at 15:06 UTC
    perldoc -q duplicate

    Abigail

Re: Unique values in array
by Paladin (Vicar) on Jun 27, 2003 at 14:58 UTC
    Or, if you do need to keep the order, try
    foreach (@values) { print "$_\n" unless $seen{$_}++; }

    The %seen hash keeps track of which elements you've seen before, and only prints ones which haven't been seen.

Re: Unique values in array
by DigitalKitty (Parson) on Jun 27, 2003 at 15:20 UTC
    Hi Anonymous Monk.

    Since you did not wish to print an array element that occured more than once (unique values only), this will work:

    #!/usr/bin/perl -w use strict; my @array = ( 2, 4, 5, 5, 7, 8, 21, 22, 22, 30 ); my %count; foreach ( @array ) { $count{$_}++; } foreach ( @array ) { print "$_ " if $count{$_} < 2; } Output: 2 4 7 8 21 30

    Hope this helps,
    -Katie.
Re: Unique values in array
by Zaxo (Archbishop) on Jun 27, 2003 at 15:08 UTC

    You can print unique values in array order using a variation on the standard hash trick:

    my %unique; @unique{@values} = (); for (@values) { next unless exists $unique{$_}; print $_, $/; delete $unique{$_}; }

    Update: A simpler way that leaves you with the %unique hash populated:

    my %unique; for (@values) { next if exists $unique{$_}; print $_, $/; $unique{$_}++; }

    After Compline,
    Zaxo

Re: Unique values in array
by artist (Parson) on Jun 27, 2003 at 15:10 UTC