Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Max value

by ameezys (Acolyte)
on Apr 16, 2019 at 14:11 UTC ( [id://1232659]=perlquestion: print w/replies, xml ) Need Help??

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

I have the code as below

my %hashName = (a => 1, b => 2, c => 3); my $max = 0; $_ > $max and $max = $_ for values %hashName; print $max;

So this will only print the value 3 right? How do I print along with the letter c when it displays 3

Replies are listed 'Best First'.
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]
Re: Max value
by Athanasius (Archbishop) on Apr 16, 2019 at 15:19 UTC

    In the spirit of TMTOWTDI:

    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,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

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{$_}.

Re: Max value
by Tux (Canon) on Apr 17, 2019 at 06:13 UTC

    In the same vane as tybalt89's example. A bit slower but maybe less obscure:

    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
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". ;-)
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"; }
      Managing two arrays in parallel is probably not the best design. Some other data structure, such for example as an array of hashes, would probably be better.

      But anyway, you can loop over the indices of the first array and keep track of the index corresponding to the max value, and then use the max index in the other array. Something like this (untested):

      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.
        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.

        Mind showing an example for that? I still don't understand how to do it.

      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
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?
      #!/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

        [-@$a..-2] would have been slightly more obscure IMHO ;-)


        Give a man a fish:  <%-{-{-{-<

      #!/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.
      Another one variant:
      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

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (3)
As of 2024-04-19 19:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found