Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Remove Duplicates from Array

by jpk236 (Monk)
on Oct 31, 2008 at 20:49 UTC ( [id://720781]=perlquestion: print w/replies, xml ) Need Help??

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

Fellow Monks:

I've been using the following method to remove duplicates from Array's for quite some time, and it just dawned on me today that I have no why the syntax is the way it is, or even really how it works.

I'm particularly curious why is the unique written as @unique in the first line?

Feel free to shed anymore insight too, as I'm sure others in the forum can benefit too.

my %unique = (); @unique{@array} = (); @array = sort keys %unique;

Thanks!

- Justin

Replies are listed 'Best First'.
Re: Remove Duplicates from Array
by dragonchild (Archbishop) on Oct 31, 2008 at 21:03 UTC
    Don't do that. Use List::MoreUtils and the uniq() function. uniq() will work in cases where yours won't, such as lists of objects and other edge cases. Plus, List::MoreUtils has a ton of really good functions to have on hand.

    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
      Additionally, List::MoreUtils uniq() will maintain your list order. Using a temporary hash is tempting, but it will almost certainly change the order of elements.

        And List::MoreUtils::uniq can be faster as it tries to load a library to implement its functionality via DynaLoader. If that fails it implements a plain perl way.

        In my test (linux, perl 5.8.8 List::MoreUtils 0.21) the original List::MoreUtils::uniq is about 400% faster than my perl implementation.

        If I rename the library, so List::MoreUtils must rely on its perl implementation, my solution is about 20% - 25% faster.

        I don't want to argue against List::MoreUtils; but now I wonder about these two (perl) solutions:

        # presented in perlfaq4 - How can I remove duplicate elements from a l +ist or array? sub my_uniq { my %h; grep { !$h{$_}++ } @_; } # vs. # List::MoreUtils::uniq sub LM_uniq { my %h; map { $h{$_}++ == 0 ? $_ : () } @_; }

        I can't recognize an advantage in the usage of map and the ternary operator.

        edit: text refined
Re: Remove Duplicates from Array
by friedo (Prior) on Oct 31, 2008 at 20:58 UTC

    Using the @ in front of a hash means you're doing a hash slice, which allows you to assign multiple values to multiple keys in one step. In this case, you're creating keys out of the values in @array, and assigning them all undef (since you've got an empty list on the right-hand side of the assignment.)

    Then you extract all the keys from the hash using the keys function. Since making a duplicate hash key does not add a new key to a hash, this has the effect of removing all duplicates.

Re: Remove Duplicates from Array
by ccn (Vicar) on Oct 31, 2008 at 20:58 UTC
Re: Remove Duplicates from Array
by sanku (Beadle) on Nov 04, 2008 at 12:40 UTC
    hi, Try out this one
    push(@newunique,grep {!$ss{$_}++} @unique);
    In the above code of @newunique you will have only unique values of array.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://720781]
Approved by Perlbotics
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (3)
As of 2024-03-29 14:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found