Re: Max value
by choroba (Cardinal) on Apr 16, 2019 at 14:17 UTC
|
my %hash_name = (a => 1, b => 2, c => 3);
my $max = (keys %hash_name)[0];
$hash_name{$_} > $hash_name{$max} and $max = $_ for keys %hash_name;
print $max;
or using List::UtilsBy:
use List::UtilsBy qw{ max_by };
my %hash_name = (a => 1, b => 2, c => 3);
my $max = max_by { $hash_name{$_} } keys %hash_name;
print $max;
map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
| [reply] [d/l] [select] |
Re: Max value
by Athanasius (Archbishop) on Apr 16, 2019 at 15:19 UTC
|
use strict;
use warnings;
my %hash_name = (a => 1, b => 2, c => 3);
my ($max_key, $max_value) = each %hash_name;
while (my ($key, $value) = each %hash_name)
{
if ($value > $max_value)
{
$max_key = $key;
$max_value = $value;
}
}
printf "Max value is %d, which corresponds to key %s\n", $max_value, $
+max_key;
Output:
1:13 >perl 1994_SoPW.pl
Max value is 3, which corresponds to key c
1:18 >
See each.
Hope that helps,
| [reply] [d/l] [select] |
Re: Max value
by hdb (Monsignor) on Apr 16, 2019 at 14:39 UTC
|
Here is another solution: argmin & argmax. In your case, expensive_func($_) would just be $hashName{$_}.
| [reply] [d/l] [select] |
Re: Max value
by Tux (Canon) on Apr 17, 2019 at 06:13 UTC
|
use List::Util qw( max );
my %hashName = (a => 1, b => 2, c => 3, d => 3);
my $mx = max values %hashName;
say "$_ => $hashName{$_}" for sort grep { $hashName{$_} == $mx } keys
+%hashName;
Enjoy, Have FUN! H.Merijn
| [reply] [d/l] |
Re: Max value
by afoken (Chancellor) on Apr 16, 2019 at 17:48 UTC
|
Continued from Max value. Please don't open new threads for the same problem.
Alexander
--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
| [reply] |
Re: Max value
by ameezys (Acolyte) on Apr 17, 2019 at 07:00 UTC
|
Thank you for the replies. It helps a lot. I have one more question regarding finding the max value.
I had stored an array @arrayh = 3 3 4 4 5 5 and another array name @wire = N10 N11 N16 N19 N22 N23 .
With that, I am finding the max value in @arrayh which is 5, 5. When I print, how do I print the value selected and tally it with the same location as the one in @wire?
Meaning that when the max value is both 5,5, it will display the wire so N22 = 5, and N23 = 5.
for(my $i=0; $i < @arrayh; $i++)
{
my $max = max @arrayh;
my $add = 1;
print @arrayh,"\n";
print @wire;
print $i+1, ". Hardest to control to logic 0 is at $wire[$i] with
+value $max \n";
}
| [reply] [d/l] |
|
my $max_i;
my $max = $arrayh[0];
for my $i (0..$#arrayh) {
if ($arrayh[$i] > $max) {
$max = $arrayh[$i];
$max_i = $i;
}
}
print " Max is: $wire[$max_i]\n";
A couple of changes would be required if you can have several maximum values (such as using an array of the indices with the max value and adding a test for equality), but this is left as an exercise to the reader.
| [reply] [d/l] |
|
| [reply] |
|
|
The easy thing to do is generate a hash and then use the code that you already have to print N22=>5 N23=>5.
Adapt my previous post to allow multiple max values to be printed however you want.
#!/usr/bin/perl
use strict;
use warnings;
my @wire = qw(N10 N11 N16 N19 N22 N23);
my @arrayh = qw(3 3 4 4 5 5);
my %hash;
@hash{@wire}=@arrayh; #hash slice
foreach my $key (keys %hash)
{
print "$key => $hash{$key}\n";
}
__END__
N23 => 5
N19 => 4
N10 => 3
N16 => 4
N22 => 5
N11 => 3
| [reply] [d/l] |
Re: Max value
by ameezys (Acolyte) on Apr 16, 2019 at 16:36 UTC
|
Thank you for the replies. Another question is, if b and c has the same value which is 3. how do I display both of it? | [reply] |
|
| [reply] |
|
#!/usr/bin/perl
# https://perlmonks.org/?node_id=1232659
use strict;
use warnings;
use List::Util qw( reduce );
my %hashName = (a => 1, b => 3, c => 3);
sub allmax
{
reduce { $a->[-1] > $b->[-1] ? $a :
$a->[-1] < $b->[-1] ? $b :
[ @{$a}[0..@$a-2], @$b ] } @_;
}
my $maxref = allmax( map [ $_, $hashName{$_} ], sort keys %hashName );
print "@$maxref\n";
Outputs:
b c 3
| [reply] [d/l] [select] |
|
| [reply] [d/l] [select] |
|
#!/usr/bin/perl
use strict;
use warnings;
my %hashName = (a => 1, b => 2, c => 3, d=>3);
#sort keys by descending order of their value
my @keys = sort {$hashName{$b} <=> $hashName{$a}} keys %hashName;
my $max = $hashName{$keys[0]};
while (my $key = shift @keys)
{
last if ($hashName{$key} < $max);
print "$key=>$hashName{$key}\n";
}
__END__
c=>3
d=>3
Update: I guess I should have added some comments to this post. There are very tricky and obtuse looking sort algorithms. Don't mistake "shorter code" or more "complex code" for "better code". When working with a hash of say <50 keys, my advice is to go with simple code. I start thinking about whipping out the "Perl nuclear weapons" when sort size gets above 1,000. | [reply] [d/l] |
|
use strict;
use warnings;
my %hash_name = ( a => 1, b => 2, c => 3, d => 3 );
my %keys_of_max;
my $key_of_max;
my $numeric_cmp_result;
$numeric_cmp_result = defined $key_of_max
? ( eval join '<=>', map { $hash_name{ $_ } } $_, $key_of_max
+)
: 1
xor $numeric_cmp_result > 0 and %keys_of_max = ( $key_of_max = $_
+=> 1 )
xor ( $numeric_cmp_result or $keys_of_max{ $_ } = 1 )
for keys %hash_name;
print sort keys %keys_of_max;
OUTPUT:
Useless use of logical xor in void context at perlmonks_Max_Value.pl l
+ine 26.
cd
| [reply] [d/l] [select] |