Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Remove redundency from an array

by vc_will_do (Sexton)
on Sep 24, 2007 at 10:28 UTC ( [id://640687]=perlquestion: print w/replies, xml ) Need Help??

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

Hi Monks, I have an array
@array = (1,1,3,3,2,3,5,7,5,2);
Is there a way to remove repeating values and make the array
@array = (1,3,2,5,7);
Order of elements is NOT a big concern as I am going to sort in next step. Thanks In Advance

Replies are listed 'Best First'.
Re: Remove redundency from an array
by oha (Friar) on Sep 24, 2007 at 10:45 UTC
Re: Remove redundency from an array
by marto (Cardinal) on Sep 24, 2007 at 10:45 UTC
Re: Remove redundency from an array
by ForgotPasswordAgain (Priest) on Sep 24, 2007 at 10:57 UTC
Re: Remove redundency from an array
by bruceb3 (Pilgrim) on Sep 24, 2007 at 10:47 UTC
    Use a hash.
    #!/usr/bin/perl use strict; use warnings; use Data::Dumper; my @array = (1,1,3,3,2,3,5,7,5,2); my %h; $h{$_}++ for @array; @array = keys %h; print Dumper \@array;
      $h{$_}++ for @array;

      That works, but is rather inefficient. Much better is to assign to a hash slice:

      @h{@array} = ( );
      A word spoken in Mind will reach its own level, in the objective world, by its own weight
        Bruce and jd's solution are both fine and far less ugly than the FAQ. Is there a reason these solutions aren't on there and the FAQ version is using splice?
Re: Remove redundency from an array
by lyklev (Pilgrim) on Sep 24, 2007 at 19:33 UTC
    Most of the answers given involve a hash, which is a good idea; the reason for this is that arrays are good for storing, but not for looking up information - hashes are much better suitable for that. You might want to redesign your program slightly, so you store your information in a hash to start with.

    However, since you will be sorting the array, there might be a different approach: first sort it, and since it is sorted, remove duplicate elements, which, because of the sorting, will be sequential.

    use strict; use warnings; my @array = (1,2,5,6,4,2,1,2,3,4,6,4,3,2,4,6,6); my @sorted = sort {$a <=> $b} @array; # numerically @array = (sort shift @sorted); # overwrite old array while (my $element = shift @sorted) { # if the element differs from the last added, keep it # otherwise discard if ($element != $array[-1]) { push (@array, $element); } } # array is now sorted, no duplicate elements
      The idea is sound. Depending on how many duplicates there are, it may end up more expensive (since you're sorting the entire array, instead of only the unique items). Also, the line @array = (sort shift @sorted) is really...odd. Why not just @array = shift @sorted? Additionally, I think instead of while (my $element = shift @sorted) { I would have just used for (@sorted){, unless there's a reason you really want to destroy the sorted version as you go.
        You are right, it should have been just

        @array = (shift @sorted)

        (the parentheses are to make it an array assignment).

        If there are many duplicates it might be more efficient to first remove the duplicates before sorting. But there is no transforming the array into a hash and back.

        I can't tell which is more efficient. My intention was to show a different approach. It shows again that there are many ways to do similar things.

Re: Remove redundency from an array
by mwah (Hermit) on Sep 24, 2007 at 14:20 UTC
    This is, as has shown here, a fairly
    often used and well documented task.

    Sometimes I'd use snippet that reads like
    my @array = (1,1,3,3,2,3,5,7,5,2); # uniqify without modules @array = do { @$_{@array} = (); keys %$_ };

    Regards

    M.

      Of course, that clobbers $_. Perhaps you want to insert

      local *_;
      at the beginning of that do block.

        jdporter: Of course, that clobbers $_. Perhaps you want to insert local *_; ...

        Would this (*_) be relevant here?

        $_ *might* be localized, but *_ imho not.

        consider:
        sub uinq { # local *_; # <== will fail, $_ will work @_ = do { @$_{@_}=(); keys %$_ }; @_ } my @array = (1,1,3,3,2,3,5,7,5,2); print "@{[ uinq @array ]}\n";


        Regards & thanks
        mwa
      Better to use either a lexical hash in the do-block, or an anonymous hash:
      @array = keys %{ {map {$_,undef} @array} };

      Caution: Contents may have been coded under pressure.
Re: Remove redundency from an array
by gube (Parson) on Sep 24, 2007 at 15:02 UTC

    This below code also one of the method to avoid duplicate values from array. It's lengthy code, However, it's one of the alternate method.

    my @array = (1,1,3,2,3,5,3,3,7,5,2); my (%ar_hash, @ar); for(@array) { next if($ar_hash{$_}++); push(@ar, $_); } print "@ar"; o/p : 1 3 2 5 7

      Doesn't need to be lengthy.

      my @u = do { my %seen; grep { ! $seen{$_}++ } @a };

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (2)
As of 2024-04-19 22:16 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found