16

I need to add unique elements in an array from inputs which contain several duplicate values.

How do I avoid pushing duplicate values into an Perl array?

alex
  • 6,818
  • 9
  • 52
  • 103
Subhash
  • 568
  • 1
  • 5
  • 21
  • you can use the notion of a set: http://stackoverflow.com/questions/3700037/how-can-i-represent-sets-in-perl – akonsu Apr 09 '13 at 06:31
  • There is always `List::MoreUtils` uniq function if you are not opposed to the CPAN. – squiguy Apr 09 '13 at 06:41

3 Answers3

22
push(@yourarray, $yourvalue) unless grep{$_ == $yourvalue} @yourarray;

This checks if the value is present in the array before pushing. If the value is not present it will be pushed.

If the value is not numeric you should use eq instead of ==.

Demnogonis
  • 3,172
  • 5
  • 31
  • 45
  • 3
    This solution becomes very inefficient as the array grows large--the hash method is to be preferred. –  Apr 09 '13 at 06:40
  • 1
    Above Answer is right, but it does not work if $_ is used in above/below statement, like chomp($_) while reading from a file. The following: " push(@yourarray, $yourvalue) unless $yourvalue ~~ @yourarray; " works perfectly. – Aquaholic May 14 '22 at 16:33
20

You simply need to use hash like this:

my %hash;
$hash{$key} = $value;  # you can use 1 as $value
...

This will automatically overwrite duplicate keys.

When you need to print it, simply use:

foreach my $key (keys %hash) {
    # do something with $key
}

If you need to sort keys, use

foreach my $key (sort keys %hash) ...
mvp
  • 111,019
  • 13
  • 122
  • 148
3

by using ~~ we can minimum perl version is 5.10.1

use v5.10.1;
use strict;
use warnings;

my @ARRAY1 = qw/This is array of backup /;
my @ARRAY2;
my $value = "version.xml";

sub CheckPush($$) {
    my $val = shift (@_);
    my $array_ref = shift (@_);

    unless ($val ~~ @$array_ref) {
        print "$val is going to push to array\n";
        push(@$array_ref, $val);
    }

    return (@$array_ref);
} 

@ARRAY1 = CheckPush($value, \@ARRAY1);
print "out\n";

foreach (@ARRAY1) {
    print "$_\n";
}

@ARRAY2 = CheckPush ($value, \@ARRAY2);
print "out2\n";

foreach (@ARRAY2) {
    print "$_\n";
}
pevik
  • 4,523
  • 3
  • 33
  • 44
Scg
  • 989
  • 1
  • 7
  • 14
  • 3
    In short: `push(@yourarray, $yourvalue) unless $yourvalue ~~ @yourarray;` – Codr Jan 27 '17 at 07:40
  • 1
    Note that smart match was downgraded to experimental since it often acted contrary to what people expected, and had other issues. – brian d foy May 05 '21 at 05:14