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

Hello,
I have written a script by using hashes. In my script I have used values independently. At the end, I have got output of a list of hash values...but now what I am looking for is getting the keys for the values (output). In simple, I am looking for the corrosponding keys for the values (output). The following is my script. Thank you very much.

#!/usr/local/bin/perl use warnings; # open a file and assign the filehandle FILE open(FILE, "2.txt") or die("can't open myfile.txt: $!\n"); while(<FILE>) { if($_ =~ /\s+(\S+)\s+(\S+)/) { $hash{$1} = $2; push(@index,$1); push (@a2, $2); } } close(FILE); # close the filehandle $i=0; while ($i<= ($#a2 - 1)) { $c1=$a2[$i]; $c2=$a2[$i+1]; $c3=$a2[$i+2]; $c4=$a2[$i+3]; $c5=$a2[$i+4]; $c6=$a2[$i+5]; $c7=$a2[$i+6]; $c8=$a2[$i+7]; $c9=$a2[$i+8]; $i++; if (($c1<$c2) && ($c2<$c3) && ($c3<$c4) && ($c4<$c5) && ($c5>$c6) && ( +$c6>$c7) && ($c7>$c8) && ($c8>$c9)) { $peak=$c5; print $peak, "\n"; } }

20050426 Janitored by Corion: Added formatting

Replies are listed 'Best First'.
Re: Accessing keys through values
by holli (Abbot) on Apr 26, 2005 at 10:33 UTC
    In case your values are unique in the hash, you can simply reverse it
    %h = (a=>"A", "b"=>"B"); %h2 = reverse %h; print $h2{A}; #a
    If not, you'll have to iterate over the hash.
    %h = (a=>"A", "b"=>"B", "bb" => "B"); for ( keys %h ) { print $_ if $h{$_} eq "B"; }
    oh ... and please use code-tags.


    holli, /regexed monk/
      As you have seen my script, the output I am getting is in the while loop and that too in the variable called $peak. Now, I should match which key contains the $peak value. For example, I have got the output from $peak as 41.876000 45.063000 48.922000 44.042000 46.863000 44.727000 45.491000 46.154000 I should search all the keys which hold these values and print both key and value like 78.3 =====> 41.876000. In this the 78.3 is the "key" and 41.876000 is the "value" (output from $peak in the while loop).
Re: Accessing keys through values
by salva (Canon) on Apr 26, 2005 at 10:35 UTC
    as long as all the values in %hash are unique (or if you don't mind loosing keys that have repeated values), you can use:
    my %rhash = reverse %hash; my $key = $rhash{$value};
    and if you have repeated values:
    my %rhash; for (keys %hash) { no warnings 'uninitialized'; push @{$rhash{$hash{$_}}}, $_; } print("$value keys: ", join(', ', @{$rhash{$value}}), "\n");
Re: Accessing keys through values
by Roy Johnson (Monsignor) on Apr 26, 2005 at 11:59 UTC
    $c5 is just $a2[$i+4] so the corresponding key is just $index[$i+4], right?

    Update: Since the only thing you ever print out is $c5, you can

    $c4=$a2[$i+3]; $c5=$a2[$i+4]; $i5 = $index[$i+4]; # This is new $c6=$a2[$i+5];
    and then your output might be:
    { $peak=$c5; print "$i5 = $peak\n"; }

    Caution: Contents may have been coded under pressure.
      Yes Roy, you are correct...
        Thank you very much everyone. You all have provided me excellent ideas. Hopefully, in future also you will be providing me the help whenever I need.
Re: Accessing keys through values
by inman (Curate) on Apr 26, 2005 at 13:33 UTC
    You never actually use the hash that you create. You populate and work with the arrays @index and @a2.

    In the following code, I have used array slices to extract the points which are then compared using the rising function. This should be a lot more flexible than the numerous variables and the cumbersome if statement.

Re: Accessing keys through values
by TomDLux (Vicar) on Apr 26, 2005 at 20:28 UTC

    I don't really understand what you are trying to achieve.

    You read a file into the array @a2 --- wouldn't it be better to name the array for what the data representst, for example @heights? Then you go through a window of 9 elements, to see if the central element in that window is the maximum for the window. Then you slide the window along, and try again.

    Maybe you really are trying to locate locale maxima, but if you explained what you were trying to achieve, we could help you more.

    For one thing, when you are dealing with a window from N..N+8, if N+4 really IS the local maximum, there's no point testing the windows starting at N+1, N+2, N+3, N+4. You've already established that N+4 is greater than any of N+5, N+6, N+7, N+8. So you might as well skip to the window from N+5..N+13.

    --
    TTTATCGGTCGTTATATAGATGTTTGCA