http://www.perlmonks.org?node_id=1008463

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

Hi PerlMonks,

I am interested to find out the lowest value (2) from an array i.e. @values=qw/5 3 2 9 2/; and to find the corresponding animal name(s) associated with the lowest value (2) from the array @names=qw/Cat Bat Cow Dog Rat/. I have written the following script key1.pl to find the lowest value, the position of the lowest value and then to call the animal name by position. The cmd gives the correct result for position 4(Rat) and not for 2(Cow). Since the lowest value 2 appears at two positions in the array, the correct result should be Cow (position 2) and Rat (position 4). I am at my wit's end to get the correct result. May I request perlmonks to provide some suggestions. I know that %hash can be used but use of %hash appears a little complicated to me. In fact, I tried using %hash but failed. Then I have tried using the given approach i.e. lowest value->position-> calling the name.

Here goes the code for key1.pl

#!/usr/bin/perl use warnings; ## To find lowest value and to call by reference: @values=qw/5 3 2 12 2/; @names=qw/Cat Bat Cow Dog Rat/; # To find the lowest value from the array A: $min=999; foreach my $item (@values) {$min=$item if $min > $item;} print"\n\n Lowest value= $min\n"; # To find the position of LOWEST Value(2) in Array values: @array_element_pos{@values}=(0..$#values); $i=$array_element_pos{$min}; print"\n Positions of Lowest Value(2)= $i (should be 2 & 4)\n"; # To extract corresponding animal name from Array names: print"\n The animal names are (should be Cow & Rat): ".$names[$i]."\n" +; exit;

I have got the following wrong results:

C:\Users\x>cd desktop C:\Users\x\Desktop>key1.pl Lowest value= 2 Positions of Lowest Value(2)= 4 (should be 2 & 4) The animal names are (should be Cow & Rat): Rat

But the correct results should look like:

Lowest value= 2 Positions of Lowest Value(2)= 2 4 (should be 2 & 4) The animal names are (should be Cow & Rat): Cow Rat

Replies are listed 'Best First'.
Re: How can one call the lowest value of an array by reference?
by GrandFather (Saint) on Dec 12, 2012 at 10:05 UTC

    Trying to maintain parallel arrays in that fashion if fraught with peril. Instead use a data structure where you can treat each data pair as an entity. One way to do that would be to use OO and generate an object for each animal. For the current sample a simple hash will suffice. Consider:

    use strict; use warnings; my %animals = ( Cat => 5, Bat => 3, Cow => 2, Dog => 12, Rat => 2 ); my %byValue; push @{$byValue{$animals{$_}}}, $_ for keys %animals; my @ordered = sort {$a <=> $b} keys %byValue; print "$_: @{$byValue{$_}}\n" for @ordered;

    Prints:

    2: Rat Cow 3: Bat 5: Cat 12: Dog

    Note the use of the reverse lookup hash byValue to ease accessing the animals in sorted order.

    True laziness is hard work

      Hi GrandFather,

      Thanks for your code.

      With kind regards,

Re: How can one call the lowest value of an array by reference?
by davido (Cardinal) on Dec 12, 2012 at 08:16 UTC

    This could probably be refactored more elegantly, but it seems to do the job in a single pass without undue complexity.

    use strict; use warnings; my @values = qw( 5 3 2 12 2 ); my @names = qw( Cat Bat Cow Dog Rat ); my $min; my @indices; foreach my $ix ( 0 .. $#values ) { if( ! defined $min or $values[$ix] < $min ) { @indices = ($ix); $min = $values[$ix]; } elsif( $min == $values[$ix] ) { push @indices, $ix; } } print "Lowest value: $min\n"; print "$_ => $names[$_]\n" for @indices;

    Dave

      Hi Dave,

      Thanks for your prompt reply. Your code is simple for me to understand. It has solved my problem.

      With regards,

Re: How can one call the lowest value of an array by reference?
by Athanasius (Archbishop) on Dec 12, 2012 at 08:05 UTC

    Here is one way:

    #! perl use Modern::Perl; use List::Util qw( min ); my @vals = qw( 5 3 2 12 2 ); my @names = qw( Cat Bat Cow Dog Rat ); my $min_val = min @vals; my @indices = grep { $vals[$_] == $min_val } (0 .. $#vals); for (@indices) { printf "Lowest value: %d, index: %d, corresponding name: %s\n", $min_val, $_, $names[$_]; }

    Output:

    18:01 >perl 429_SoPW.pl Lowest value: 2, index: 2, corresponding name: Cow Lowest value: 2, index: 4, corresponding name: Rat 18:03 >

    Hope that helps,

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

      Hi Athanasius,

      Thanks for your quick reply. Your code has worked nicely. It has solved my problem.

      Regards,

Re: How can one call the lowest value of an array by reference?
by Kenosis (Priest) on Dec 12, 2012 at 08:34 UTC

    Here's another option:

    use Modern::Perl; my @values = qw/5 3 2 12 2/; my @names = qw/Cat Bat Cow Dog Rat/; my %hash; push @{ $hash{ $values[$_] } }, $_ for 0 .. $#values; my $lowest = ( sort { $a <=> $b } keys %hash )[0]; say "Positions of Lowest Value ($lowest) = @{$hash{$lowest}}"; print 'The animal names are: '; print join ' ', map $names[$_], @{$hash{$lowest}};

    Output:

    Positions of Lowest Value (2) = 2 4 The animal names are: Cow Rat

      Hi Kenosis,

      Thank you very much for your prompt reply and the code. It has worked well and has solved my problem.

      With Regards,

Re: How can one call the lowest value of an array by reference?
by ww (Archbishop) on Dec 12, 2012 at 13:14 UTC
    Please explain your criteria for "lowest value."

    "Lowest value" is singular, but your narrative and requirements treat it as if it meant "the two lowest values (plural)."

    So why not "three lowest"? ... or "four?"

    P.S added:

    And how if understanding a hash is "a little complicated to me" how did you manage to write

    011: @array_element_pos{@values}=(0..$#values);
    012: $i=$array_element_pos{$min};

    You seem to be stuck at the same old stand (Re: How can one create a folder B in D drive and save results in a text file inside B using perl script?) -- presenting incoherent questions and, when you include code, doing so with samples that appear to be beyond your competence, cargo-culted in bits and pieces, or un-compilable.

    Please, do yourself (and us) a favor, and get the basics right (yes, hashes are among those basics). You'll find that further learning comes easier.

      Homework! =)