http://www.perlmonks.org?node_id=667733

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

After locating the 15 character long values .There are when i have the same 15 character long value reapeated number of times !!!! Now i wish to find only the unique ones occurence of it. I found this code on the web. What do you suggest me here.
%seen = (); @uniq = (); foreach $item (@proc_name1) { unless ($seen{$item}) { $seen{$item} = 1; push (@uniq, $item); } }

Replies are listed 'Best First'.
Re: to select unique characters
by mickeyn (Priest) on Feb 13, 2008 at 07:26 UTC
    A little shorter syntax:

    my %seen = map {$_ => undef} @proc_name1; my @uniq = keys %seen;
    Enjoy,
    Mickey
Re: to select unique characters
by jwkrahn (Abbot) on Feb 13, 2008 at 08:03 UTC

    That is usually written like this:

    my %seen; my @uniq = grep !$seen{$_}++, @proc_name1;

    And if you want to localize the scope of the hash you could do it like this:

    my @uniq = do { my %seen; grep !$seen{$_}++, @proc_name1; };
Re: to select unique characters
by johngg (Canon) on Feb 13, 2008 at 10:42 UTC
    The common idiom seems to be

    my %seen; my @uniq = grep { ! $seen{$_} ++ } @arr;

    but using a hash slice seems to be a bit faster. I should warn that I have a chequered history with benchmarks so take this with a pinch of salt.

    use strict; use warnings; use Benchmark q{cmpthese}; my @arr = ( q{a} .. q{z} ) x 1000; cmpthese( -10, { useGrep => sub { my %seen; return grep { ! $seen{$_} ++ } @arr; }, useSlice => sub { my %seen; @seen{@arr} = (); return keys %seen; }, });

    The output.

    Rate useGrep useSlice useGrep 13.0/s -- -63% useSlice 35.2/s 172% --

    If you need to preserve the order of the array then you should use the grep method.

    I hope this is of interest.

    Cheers,

    JohnGG

Re: to select unique characters
by kyle (Abbot) on Feb 13, 2008 at 17:53 UTC

    Here's an even shorter way, if you don't want to use a variable at all:

    my @uniq = keys %{{ map { $_ => undef } @proc_name1 }};

    However, this is slower than the slice and grep methods, both.

    Rate useRef useGrep useSlice useRef 74.3/s -- -64% -84% useGrep 204/s 175% -- -56% useSlice 464/s 525% 127% --

    (Thanks to johngg for the tests in Re: to select unique characters).