Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Getiing keys or values of a file based hash

by shabird (Sexton)
on Feb 27, 2020 at 17:56 UTC ( [id://11113506]=perlquestion: print w/replies, xml ) Need Help??

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

I have a file named "gene.txt", which looks like this GeneName GeneType

APOL4 protein_coding CYP2C8 protein_coding NAALADL2 protein_coding NANOS3 protein_coding C20orf204 protein_coding MIR429 miRNA MIR200A miRNA MIR200B miRNA I have a file named "gene.txt", which looks like this GeneName GeneType APOL4 protein_coding CYP2C8 protein_coding NAALADL2 protein_coding NANOS3 protein_coding C20orf204 protein_coding MIR429 miRNA MIR200A miRNA MIR200B miRNA
i have read that file in perl and assigned the values to a hash. Now i want to get the keys or values from that file as i have assigned it to hash but i am unable to get those. my point is to i want to get keys by using the keys() method but its not printing the values on the left as keys and its not printing anything i don't know why i will be very thankful if anyone could help me. Thank you in advance.

#!/usr/bin/perl -w use strict; open FILE1, "/Desktop/gene.txt" or die; my %hash; while (my $line=<FILE1>) { chomp $line; # print $line,"\n"; (my $word1,my $word2) = split /:/, $line; $hash{$word1} = $word2; } # Print hash for testinf purposes while ( my ($k,$v) = each %hash ) { # print "Key $k $v\n"; @keys = keys(%hash); print @keys; }

Replies are listed 'Best First'.
Re: Getiing keys or values of a file based hash
by Fletch (Bishop) on Feb 27, 2020 at 18:34 UTC

    For one thing your sample file has no ":" characters in it so your split isn't doing what you want; use my( $k, $v ) = split( /\s+/, $line ) instead.

    $ perl -E '$_=qq{GeneName GeneType};my($foo,$bar)=split(/:/,$_);say + qq{foo: $foo\nbar: $bar}' foo: GeneName GeneType bar: $ perl -E '$_=qq{GeneName GeneType};my($foo,$bar)=split(/\s+/,$_);s +ay qq{foo: $foo\nbar: $bar}' foo: GeneName bar: GeneType

    That aside, your commented out printing code should have been fine. My guess is since your split wasn't working the way you expected you went and tried to do what you've got now, which just doesn't make sense (walk over every item in the hash, and for each item print a list of all the keys in the hash). Alternately consider using Data::Dumper or YAML::XS or the like to print out the contents.

    $ perl -E '%hash = qw( a b c d ); while( my( $k, $v ) = each %hash ) { + say qq{$k => $v}; }' c => d a => b

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

Re: Getiing keys or values of a file based hash
by kcott (Archbishop) on Feb 28, 2020 at 07:50 UTC

    G'day shabird,

    Welcome to the Monastery.

    You've posted your input data twice. Working past that, is it really double-spaced as you've shown? The output from your 'print $line,"\n";' would have been useful for us; however, you've commented that out.

    There's another bigger problem. You said "its not printing anything". The code you posted would have printed something like:

    Global symbol "@keys" requires explicit package name ... Execution ... aborted due to compilation errors.

    For future reference, please

    • take more care when posting input data,
    • post the actual code you are running, and
    • provide us with the exact output you get (even if that's only error or warning messages).

    If you had made a mistake by trying to split on non-existent colons, you still would have got the keys but the values would have been all undef. Here's a quick example:

    $ perl -e ' my $x = "MIR200B miRNA"; my %h; my ($k, $v) = split /:/, $x; $h{$k} = $v; use Data::Dumper; print Dumper(\%h); ' $VAR1 = { 'MIR200B miRNA' => undef };

    Given there's so many question marks over the data and the code, it's difficult to advise you. The following may be close to what you were trying achieve; or, at least, provide some insight into how you might proceed.

    #!/usr/bin/env perl use strict; use warnings; my %data; while (<DATA>) { next if $. == 1; chomp; next unless length; my ($k, $v) = split; $data{$k} = $v; } # To test result use Data::Dumper; print "*** Hash ***\n"; print Dumper(\%data); print "*** Keys ***\n"; print "$_\n" for keys %data; print "*** Values ***\n"; print "$_\n" for values %data; __DATA__ GeneName GeneType APOL4 protein_coding CYP2C8 protein_coding NAALADL2 protein_coding NANOS3 protein_coding C20orf204 protein_coding MIR429 miRNA MIR200A miRNA MIR200B miRNA

    Output:

    *** Hash *** $VAR1 = { 'NANOS3' => 'protein_coding', 'C20orf204' => 'protein_coding', 'APOL4' => 'protein_coding', 'MIR429' => 'miRNA', 'NAALADL2' => 'protein_coding', 'MIR200B' => 'miRNA', 'MIR200A' => 'miRNA', 'CYP2C8' => 'protein_coding' }; *** Keys *** NANOS3 C20orf204 APOL4 MIR429 NAALADL2 MIR200B MIR200A CYP2C8 *** Values *** protein_coding protein_coding protein_coding miRNA protein_coding miRNA miRNA protein_coding

    — Ken

Re: Getiing keys or values of a file based hash
by zubenel0 (Sexton) on Feb 27, 2020 at 18:51 UTC
    To add to Fletch answer I have ran your code and noticed an error message that array @keys is not declared and you can do this with something as "my @keys;". You could delete the last while loop and save the keys in array @keys. And then cycle through the array like this:
    foreach my $key ( @keys) { print $key,"\n"; }
Re: Getting keys or values of a file based hash
by Eily (Monsignor) on Feb 28, 2020 at 16:55 UTC

    Beside the fact that your code doesn't compile, there is another issue with the while loop, keys resets the iterator so each starts from the first pair each time. Your loop basically means that while you get the first key/value pair, print all the keys; which is an infinite loop.

    Fletch is probably right and you probably just got this frankencode while trying different ways to debug, but FYI you should avoid using keys or values inside a while(each) loop.

      > you should avoid using keys or values inside a while(each) loop.

      It's easier to always avoid each which is the advice I listen to.

      map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (6)
As of 2024-04-19 06:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found