PetreAdi has asked for the wisdom of the Perl Monks concerning the following question:
This node falls below the community's threshold of quality. You may see it by logging in.
Re: How do I remove the duplicates from the array?
by choroba (Cardinal) 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).
| [reply] [Watch: Dir/Any] [d/l] |
|
... 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.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
@output = ( -20, , ,1, , , ,9,3, ,-4, 5, ,20);
@output1 = ( 10, , ,9, , , ,1,3, , 5, 5, ,30);
$#array==$#array1==$#output==$#output1
| [reply] [Watch: Dir/Any] [d/l] |
|
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;
| [reply] [Watch: Dir/Any] [d/l] |
|
|
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
}
}
| [reply] [Watch: Dir/Any] [d/l] |
Re: How do I remove the duplicates from the array?
by ww (Archbishop) 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.
| [reply] [Watch: Dir/Any] |
Re: How do I remove the duplicates from the array?
by davido (Cardinal) on Sep 25, 2013 at 19:13 UTC
|
| [reply] [Watch: Dir/Any] |
Re: How do I remove the duplicates from the array?
by hdb (Monsignor) on Sep 26, 2013 at 12:24 UTC
|
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";
| [reply] [Watch: Dir/Any] [d/l] |
|
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)
| [reply] [Watch: Dir/Any] [d/l] |
|
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.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
|
|
Re: How do I remove the duplicates from the array?
by Anonymous Monk on Sep 25, 2013 at 22:55 UTC
|
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
| [reply] [Watch: Dir/Any] [d/l] |
|
| [reply] [Watch: Dir/Any] |
Re: How do I remove the duplicates from the array?
by LanX (Saint) 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 | [reply] [Watch: Dir/Any] |
Re: How do I remove the duplicates from the array?
by pvaldes (Chaplain) 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 "$_, "};
| [reply] [Watch: Dir/Any] [d/l] |
|
|