Beefy Boxes and Bandwidth Generously Provided by pair Networks Bob
go ahead... be a heretic
 
PerlMonks  

How do I remove the duplicates from the array?

by PetreAdi (Novice)
on Sep 25, 2013 at 19:08 UTC ( #1055728=perlquestion: print w/ replies, xml ) Need Help??
PetreAdi has asked for the wisdom of the Perl Monks concerning the following question:

I have 2 array

@array = (-20,20,1,1,2,2,2,9,3,-4,-4,5,-20,20); @array1 = ( 10,11,7,9,3,3,3,1,3, 4, 5,5, 1,30);

The output should be:

@output = ( -20, , ,1, , , ,9,3, ,-4, 5, ,20); @output1 = ( 10, , ,9, , , ,1,3, , 5, 5, ,30);

-20 because 10>1

20 because 11<30

2 delete all

Keep the highest element

Very good

Thank you

Comment on How do I remove the duplicates from the array?
Select or Download Code
Re: How do I remove the duplicates from the array?
by davido (Archbishop) on Sep 25, 2013 at 19:13 UTC

    Could you please explain the rules a little more clearly?


    Dave

Re: How do I remove the duplicates from the array?
by ww (Bishop) on Sep 25, 2013 at 19:14 UTC

    When I saw your title, I thought "hash."

    But when I read your spec, I found an entirely different question. So what is the rule/logic by which you have determined that the process should behave as in your spec, and how does that relate to the data you've shown.

Re: How do I remove the duplicates from the array?
by choroba (Abbot) on Sep 25, 2013 at 20:09 UTC
    Your specification is very unlclear. That is what I made of it: you want to keep a tuple in both arrays if the number in the top array (key) appears only once or the corresponding value from array 2 is greater than all corresponding values to the same key.
    #!/usr/bin/perl use warnings; use strict; my @array = qw(-20 20 1 1 2 2 2 9 3 -4 -4 5 -20 20 7 7 7); my @array1 = qw( 10 11 7 9 3 3 3 1 3 4 5 5 1 30 8 7 8); my %hash; for my $i (0 .. $#array) { my $first = $array[$i]; my $second = $array1[$i]; if (not exists $hash{$first}{highest}) { # The key seen for the first time. $hash{$first}{highest} = $second; } else { # The highest value seen again. $hash{$first}{delete} = 1 if $second == $hash{$first}{highest} +; # A new highest value. if ($second > $hash{$first}{highest}) { $hash{$first}{highest} = $second; $hash{$first}{delete} = 0; } } } # Delete repeated max values. for my $key (keys %hash) { delete $hash{$key} if $hash{$key}{delete}; } my (@output, @output1); for my $i (0 .. $#array) { if (exists $hash{ $array[$i] } and $array1[$i] == $hash{ $array[$i] }{highest}) { push @output, $array[$i]; push @output1, $array1[$i]; } } print "@output\n@output1\n";

    Updated : Fixed a bug, added 7 to show the problem (the previous version did not delete 7 because there was a lesser value).

    لսႽ ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
      ... what I made of it ...

      My congratulations and a ++ if you made anything at all of it. I could make nothing whatsoever, especially of the  , , and  , , , bits in the output array examples.

      Very good

      But i need

      @output = ( -20, , ,1, , , ,9,3, ,-4, 5, ,20); @output1 = ( 10, , ,9, , , ,1,3, , 5, 5, ,30); $#array==$#array1==$#output==$#output1

        In that case you can add an else block to the code generating the arrays @output and @output1 in choroba's code.

        my (@output, @output1); for my $i (0 .. $#array) { if (exists $hash{ $array[$i] } and $array1[$i] == $hash{ $array[$i] }{highest}) { push @output, $array[$i]; push @output1, $array1[$i]; } else { push @output, ''; # or use spaces ' ' here push @output1, ''; # or whatever you want } }

        Please, be more precise. Even if Perl can "do what you mean", sometimes you have to be careful.
        @long = (1, 2, 3, 4, 5); @sparse = (1, , , 4, ); @short = (1, 4); print "Equals\n" if $#long == $#sparse; print "Shorter\n" if $#short == $#sparse;
        لսႽ ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: How do I remove the duplicates from the array?
by Anonymous Monk on Sep 25, 2013 at 22:55 UTC

    This one assumes integer values:

    use strict; use warnings; # Including choroba's sevens. my @array = qw(-20 20 1 1 2 2 2 9 3 -4 -4 5 -20 20 7 7 7); my @array1 = qw( 10 11 7 9 3 3 3 1 3 4 5 5 1 30 8 7 8); # Tuple of array elements as "key"/"val" pairs. my @pairs; # Max "val" for each "key". my %max; for (0..$#array) { my $key = $array[$_]; my $val = $array1[$_]; my $max = $max{$key}; push @pairs, [$key, $val]; if (defined $max) { next if $val < $max; # For the "2"/"3" pairs. Only want "highlander" max, so # increase by a fraction (assumes integers in @array1). $val += 0.5 if $val == $max; } $max{$key} = $val; } my (@output, @output1); for (@pairs) { my ($key, $val) = @$_; next unless $val == $max{$key}; push @output, $key; push @output1, $val; } say join ',', map sprintf('%3d', $_), @$_ for \@output, \@output1; __END__ -20, 1, 9, 3, -4, 5, 20 10, 9, 1, 3, 5, 5, 30

      Very good

      Thank you

Re: How do I remove the duplicates from the array?
by LanX (Abbot) on Sep 26, 2013 at 10:08 UTC
    > -20 because 10>1

    > 20 because 11<30

    > 2 delete all

    Wait! On Wednesdays invert the result!

    > Keep the highest element

    except on Ramadan!

    > Very good

    > Thank you

    your welcome! =)

    Cheers Rolf

    ( addicted to the Perl Programming Language)

    update

    o sorry, it was on Tuesdays

Re: How do I remove the duplicates from the array?
by hdb (Parson) on Sep 26, 2013 at 12:24 UTC

    Here is an answer as cryptic (and somewhat wasteful) as your requirements (ignoring LanX extras):

    use warnings; use strict; my @array = qw(-20 20 1 1 2 2 2 9 3 -4 -4 5 -20 20 7 7 7); my @array1 = qw( 10 11 7 9 3 3 3 1 3 4 5 5 1 30 8 7 8); for( map{ my $k=$_; [ sort{ $array1[$b]<=>$array1[$a] } grep{ $k eq $a +rray[$_] } 0..$#array ] } @array ) { shift @$_ if @$_==1 or $array1[$$_[0]] ne $array1[$$_[1]]; $array[$_] = $array1[$_] = '' for @$_; } $"=','; print "\@output = (@array);\n\@output1 = (@array1);\n";
      maybe less cryptic?

      DB<154> @a0 = (-20,20,1,1,2,2,2,9,3,-4,-4,5,-20,20); => (-20, 20, 1, 1, 2, 2, 2, 9, 3, -4, -4, 5, -20, 20) DB<155> @a1 = ( 10,11,7,9,3,3,3,1,3, 4, 5,5, 1,30); => (10, 11, 7, 9, 3, 3, 3, 1, 3, 4, 5, 5, 1, 30) DB<156> map { push @{$group{$a0[$_]}},$a1[$_] } 0..$#a0 DB<157> sub highlander { my @sort = sort @{ shift() } ; return $sort[-1]>$sort[0] ? $sort[-1] : undef } DB<158> @high{keys %group } = map { highlander($_) } values %group => (undef, 5, undef, undef, 30, 9, 10, undef) DB<159> map { ($a0[$_],$a1[$_])=() if $a1[$_] != $high{ $a0[$_] } } +0..$#a0 DB<160> \@a0 => [ -20, undef, undef, 1, undef, undef, undef, undef, undef, undef, -4, undef, undef, 20, ] DB<161> \@a1 => [ 10, undef, undef, 9, undef, undef, undef, undef, undef, undef, 5, undef, undef, 30, ]

      Cheers Rolf

      ( addicted to the Perl Programming Language)

        I do not understand the line $sort[-1]>$sort[0] ? $sort[-1] : undef. What if the values are 7, 8, 8? How will it discard the whole thing? I know the OPs spec is rather cryptic but my understanding was, that the values are to be blanked out if the max occurs more than once.

Re: How do I remove the duplicates from the array?
by pvaldes (Hermit) on Sep 26, 2013 at 20:40 UTC
    use List::MoreUtils qw{uniq}; my @array = uniq (-20, 20, 1, 1, 2, 2, 2, 9, 3, -4, -4, 5, -20, 20, 7 +, 7, 7); foreach (@array){print "$_, "};

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (7)
As of 2014-04-21 16:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (497 votes), past polls