Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Creating hash: Key is unique string in array element, value is number of times it appears

by putmant (Initiate)
on Oct 25, 2011 at 23:35 UTC ( [id://933744]=perlquestion: print w/replies, xml ) Need Help??

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

I am new to Perl. I have created an array of the lines in my file (split on the white space. I want to exclude the query line. I am interested in element 2 (which is a string ie Streptococcus). I want to create a hash where a new key is created each time a novel string appears and the value will be 1. Each time it sees a string that has already been seen, I want to add 1 to the value of that key. My code returns a new key for every line with the value 2...What am I doing wrong? Thanks

#Example data: #Query= 16sV5:44:FC62N5DAAXX:7:1:18808:1248 1:N:0: #1111599 AB563244.1 Streptococcus macedonicus str. W28 #1111215 AB563262.1 Streptococcus equinus str. MTS6 #repeats thousands of times... while (my $line = <IN>) { chomp $line; if ($line =~ /Query=/) { } else{ my @hit = split (/\s/, $line); my %genus = ($hit[2] , 1) ; if (exists ( $genus {$hit[2]})) { $genus{$hit[2]}++; } else{ $genus{$hit[2]} = 1; } my @keys = keys %genus; my @values = values %genus; print "@keys\n@values\n"; } next; }
  • Comment on Creating hash: Key is unique string in array element, value is number of times it appears
  • Download Code

Replies are listed 'Best First'.
Re: Creating hash: Key is unique string in array element, value is number of times it appears
by toolic (Bishop) on Oct 25, 2011 at 23:51 UTC
    If you want to accumulate all your data into one hash, you need to declare it outside the while loop:
    use warnings; use strict; use Data::Dumper; my %genus; while ( my $line = <DATA> ) { chomp $line; next if $line =~ /Query=/; my @hit = split( /\s/, $line ); $genus{ $hit[2] }++; } print Dumper(\%genus); __DATA__ Query= 16sV5:44:FC62N5DAAXX:7:1:18808:1248 1:N:0: 1111599 AB563244.1 Streptococcus macedonicus str. W28 1111215 AB563262.1 Streptococcus equinus str. MTS6
    prints...
    $VAR1 = { 'Streptococcus' => 2 };

      Thank you so much! This worked perfect. Thanks to the other repilers as well

Re: Creating hash: Key is unique string in array element, value is number of times it appears
by spazm (Monk) on Oct 26, 2011 at 01:14 UTC
    In perl, explicit code like this is not necessary as it would be in something more verbose like java or python. Perl has a concept of autovivification, where new values burst into being when needed. Also, ++ on a false value will return 1.

    In the case where $hit[2] is not a key in %genus, requesting the key will create a corresponding value of undef. Incrementing this value will return 1.

    so this snippet:

    #old snippet if (exists ( $genus {$hit[2]})) { $genus{$hit[2]}++; } else{ $genus{$hit[2]} = 1; }
    can be reduced to this snippet:
    #new snippet $genus{ $hit[2] }++

    Example:

    %genus = { } ; #genus is empty $genus{ foo }; #requests foo entry, and throws away. #genus is now { foo => undef } $genus{ foo } ++; # genus is now { foo => 1 }
    http://en.wikipedia.org/wiki/Autovivification
      %genus = { } ; #genus is empty

      Let's try that!

      knoppix@Microknoppix:~$ perl -Mstrict -wE 'my %genus = {};' Reference found where even-sized list expected at -e line 1. knoppix@Microknoppix:~$

      You probably meant to use parentheses rather than curly braces, which construct a reference to an anonymous hash.

      knoppix@Microknoppix:~$ perl -Mstrict -wE 'my %genus = ();' knoppix@Microknoppix:~$

      I hope this is helpful.

      Cheers,

      JohnGG

Re: Creating hash: Key is unique string in array element, value is number of times it appears
by Khen1950fx (Canon) on Oct 26, 2011 at 02:54 UTC
    I would try something more like this:
    #!/usr/bin/perl use strict; use warnings; use Data::Dumper::Concise; my(@array) = qw( 1111599 AB563244.1 Streptococcus macedonicus str. W28 + 1111215 AB563262.1 Streptococcus equinus str. MTS6 ); print Dumper( "Occur twice: @{numbers(\@array, 2);}" ); sub numbers { my ($newArray, $n) = (shift @_, shift @_); my(%count)= (); my(@temp_arr) = grep( {$count{$_} == $n;} grep ({++$count{$_} == 1;} @$newArray)); print "\%count:\n"; while ( my ($key, $value) = each(%count) ) { print Dumper( "$key => $value" ); } return \@temp_arr; }

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (3)
As of 2024-04-25 07:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found