Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

hash of arrays

by Anonymous Monk
on Oct 26, 2011 at 09:01 UTC ( #933825=perlquestion: print w/replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi dear Monks I'm so puzzled with a very stupid error that I cant figure it out. I have my data in a tab separated file as:
mv89psg6zh4 A bird in a sink keeps getting under the running water +from a faucet. mv89psg6zh4 A bird is bathing in a sink. mv89psg6zh4 A bird is splashing around under a running faucet. mv89psg6zh4 A bird is bathing in a sink. mv89psg6zh4 A bird is standing in a sink drinking water that is pou +ring out of the facet. mv89psg6zh4 A faucet is running while a bird stands in the sink bel +ow. mv89psg6zh4 A bird is playing in a sink with running water. mv89psg6zh4 A bird is playing in tap water. mv89psg6zh4 A bird is bathing in the sink. mv89psg6zh4 A bird is taking a bath.
my code suppose to run and store all second column string to the array for each key of the first column.
use strict; use warnings; use open IN => ':utf8'; use open OUT => ':utf8'; use Encode; my $file1 = shift; my (%hash,$key); open( IN1, "<:encoding(utf8)", $file1 ); while (<IN1>) { chomp; my ($video, $p) = split /\t/; chomp ($video, $p); push( @{$hash{$video}}, $p ); #print "array of hash of $video <==== $p\n"; } foreach $key ( keys %hash ) { print "$key: @{ $hash{$key} }\n" } close IN1;
I get in the output this:
A bird is taking a bath. sink..h running water.sink below.g out of th +e facet.cet.
Where is wrong in my code? I've tried many solutions but they did not work either! Thanks in advance.

Replies are listed 'Best First'.
Re: hash of arrays
by GrandFather (Sage) on Oct 26, 2011 at 09:22 UTC

    What did you expect to see? Have you noticed that for your sample data all the keys are the same? Is that what you intended?

    A useful trick that will help us solve your problem for you is to combine your data and sample code as follows:

    use strict; use warnings; use open IN => ':utf8'; use open OUT => ':utf8'; use Encode; my $str = <<STR; mv89psg6zh4 A bird in a sink keeps getting under the running water +from a faucet. mv89psg6zh4 A bird is bathing in a sink. mv89psg6zh4 A bird is splashing around under a running faucet. mv89psg6zh4 A bird is bathing in a sink. mv89psg6zh4 A bird is standing in a sink drinking water that is pou +ring out of the facet. mv89psg6zh4 A faucet is running while a bird stands in the sink bel +ow. mv89psg6zh4 A bird is playing in a sink with running water. mv89psg6zh5 A bird is playing in tap water. mv89psg6zh5 A bird is bathing in the sink. mv89psg6zh5 A bird is taking a bath. STR my %hash; open my $inFile, '<:encoding(utf8)', \$str; while (<$inFile>) { chomp; my ($video, $p) = split /\t/; push (@{$hash{$video}}, $p); } print "$_:\n ", join ("\n ", @{$hash{$_}}), "\n" for keys %hash;

    Prints:

    mv89psg6zh4: A bird in a sink keeps getting under the running water from a fauce +t. A bird is bathing in a sink. A bird is splashing around under a running faucet. A bird is bathing in a sink. A bird is standing in a sink drinking water that is pouring out of +the facet. A faucet is running while a bird stands in the sink below. A bird is playing in a sink with running water. mv89psg6zh5: A bird is playing in tap water. A bird is bathing in the sink. A bird is taking a bath.

    Note that I've altered some of the keys.

    True laziness is hard work
Re: hash of arrays
by i5513 (Pilgrim) on Oct 26, 2011 at 09:47 UTC

    It is because of ^M characters. See

    cat -ev yourfile
    output

    Try adding after first chomp:

    s/^M//g;

    To write ^M in vim : CTRL-v CTRL-M

    Or use dos2unix tool ..

    Regards,

      Thanks the problem solved by adding this after the chomp.
      s/\r//g;
Re: hash of arrays
by spazm (Monk) on Oct 26, 2011 at 09:09 UTC
    Your code looks roughly correct for the behavior you are expecting.

    Some minor changes:

    • The second chomp call should be removed.
    • added Data::Dumper to inspect to dump output
    • attached $key lexical to a smaller scope
    • add error checking to file open
    • close filehandle when done reading it
    • lexical filehandle $IN1 rather than global filehandle IN1
    #!/usr/bin/perl use strict; use warnings; use open IN => ':utf8'; use open OUT => ':utf8'; use Encode; use Data::Dumper; my $file1 = shift; my %hash; open( my $IN1, "<:encoding(utf8)", $file1 ) or die; while (<$IN1>) { chomp; my ($video, $p) = split /\t/; push( @{$hash{$video}}, $p ); #print "array of hash of $video <==== $p\n"; } close $IN1; foreach my $key ( keys %hash ) { print "$key: @{ $hash{$key} }\n" } print Dumper \%hash;
    output:
    mv89psg6zh4: A bird in a sink keeps getting under the running water fr +om a fauc et. A bird is bathing in a sink. A bird is splashing around under a ru +nning fau cet. A bird is bathing in a sink. A bird is standing in a sink drinkin +g water t hat is pouring out of the facet. A faucet is running while a bird stan +ds in the sink below. A bird is playing in a sink with running water. + A bird is playing in tap water. A bird is bathing in the sink. A bir +d is taking a bath. $VAR1 = { 'mv89psg6zh4' => [ 'A bird in a sink keeps getting under the r +unning water from a faucet.', 'A bird is bathing in a sink.', 'A bird is splashing around under a running + faucet.', 'A bird is bathing in a sink.', 'A bird is standing in a sink drinking wate +r that is pouring out of the facet.', 'A faucet is running while a bird stands in + the sink below.', 'A bird is playing in a sink with running w +ater.', 'A bird is playing in tap water.', 'A bird is bathing in the sink.', 'A bird is taking a bath.' ] };
      This is perl, v5.10.1 (*) built for x86_64-linux-thread-multi Copyright 1987-2009, Larry Wall Perl may be copied only under the terms of either the Artistic License + or the GNU General Public License, which may be found in the Perl 5 source ki +t. Complete documentation for Perl, including FAQ lists, should be found +on this system using "man perl" or "perldoc perl". If you have access to + the Internet, point your browser at http://www.perl.org/, the Perl Home Pa +ge.
      system:
      Linux tammuz 2.6.32-131.12.1.el6.x86_64 #1 SMP Sun Jul 31 16:44:56 EDT + 2011 x86_64 x86_64 x86_64 GNU/Linux
      And then that's extremely strange!!!!
      I do get the output of dump correct but the same output for the other :
      A bird is taking a bath. sink..h running water.sink below.g out of th +e facet.cet.
        what output do you get if you change your print loop to
        foreach my $key ( keys %hash ) { #print "$key: @{ $hash{$key} }\n" print "$key: \n"; foreach (@{$hash{$key}}) { print $_ , "\n"; } }
        Does each line get printed correctly, or are the lines garbled as in your old output?
Re: hash of arrays
by spazm (Monk) on Oct 26, 2011 at 09:07 UTC
    I downloaded your code and input file, running them I get this output:
    mv89psg6zh4: A bird in a sink keeps getting under the running water fr +om a faucet. A bird is bathing in a sink. A bird is splashing around +under a running faucet. A bird is bathing in a sink. A bird is standi +ng in a sink drinking water that is pouring out of the facet. A fauce +t is running while a bird stands in the sink below. A bird is playing + in a sink with running water. A bird is playing in tap water. A bird + is bathing in the sink. A bird is taking a bath.
    Where are you running your code? Perl version , OS, Locale ?
    % perl --version This is perl 5, version 12, subversion 3 (v5.12.3) built for darwin-th +read-multi-2level (with 2 registered patches, see perl -V for more detail) [...] % uname -a Darwin femto.local 11.0.1 Darwin Kernel Version 11.0.1: Thu Jul 28 02: +01:39 PDT 2011; root:xnu-1699.23.4~1/RELEASE_X86_64 x86_64
Re: hash of arrays
by jethro (Monsignor) on Oct 26, 2011 at 09:14 UTC

    I tried your code and I got the correct(?) output:

    mv89psg6zh4: A bird in a sink keeps getting under the running water fr +om a faucet. A bird...

    Since all your keys were the same I even changed two of them to mv89psg7zh4 and mv89psg8zh4 and again got the expexted output:

    mv89psg7zh4: A bird is playing in a sink with running water. mv89psg6zh4: A bird in a sink keeps getting under the running water fr +om a faucet. A bird is bathing in a sink. A bird is splashing around +under a running faucet. A bird is bathing in a sink. A bird is standi +ng in a sink drinking water that is pouring out of the facet. A fauce +t is running while a bird stands in the sink below. A bird is bathing + in the sink. A bird is taking a bath. mv89psg8zh4: A bird is playing in tap water.

    PS: What do you see when you uncomment the print statement inside your read loop?

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://933825]
Approved by GrandFather
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (5)
As of 2017-12-14 23:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    What programming language do you hate the most?




















    Results (414 votes). Check out past polls.

    Notices?