Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Hashes of arrays populated from a Text File

by Raya4505 (Novice)
on Feb 26, 2014 at 14:52 UTC ( [id://1076256]=perlquestion: print w/replies, xml ) Need Help??

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

Hello, oh wise ones. I posted a previous question that I was struggling with for days and someone gave me an answer within 30 minutes, so I'm hoping to be that lucky again. I am very new to PERL so please be gentle and very simple with your answers

I am trying to populate several hashes with arrays in them all from a tab delimited text file. The format of the information is:

Name1 1234

Name2 9999

Name1 5514

Name3 5415

Name2 6419

So, as you can see, I need the script to be able to go through and put the "matches" together even though they aren't in concecutive order and then populate each matching hash key with the corresponding data; ideally the results would look like this:

Name1 => '1234','5514'; so on and so forth.

Here is the code I have. It works populating, but it doesn't combine the same names and values together, it just creates a new hash for them.

#!/usr/local/bin/perl use strict; use warnings; use Data::Dumper; my %Diag; my $file = "2009.txt"; open my $fh, "<", $file or die "Can't open $file: $!"; while (<$fh>) { chomp; undef $Diag{$_}; } print Dumper \%Diag; foreach my $k (keys %Diag) { print "$k\n"; }

I've looked on here, online and in books, can't get any of the codes to work, so any help would be amazing! Thank you so much in advance!

Replies are listed 'Best First'.
Re: Hashes of arrays populated from a Text File
by toolic (Bishop) on Feb 26, 2014 at 14:57 UTC
    Use a hash-of-arrays (perldsc)
    use warnings; use strict; use Data::Dumper; my %Diag; while (<DATA>) { my ($name, $val) = split; push @{ $Diag{$name} }, $val; } print Dumper(\%Diag); __DATA__ Name1 1234 Name2 9999 Name1 5514 Name3 5415 Name2 6419

      That is what my code essentially already does. I am needing the script to combine the names that are the same and compile the date in one hash. I want the values to be able to repeat, but not the names. Sorry if that wasn't clear.

      The data should look like:

      Name1 => value1 value2 value3 Name2 => value4 value5 value5 Name3 => value6 value7 value8
        Unless I've mis-interpreted it, having done the hard work as posited by toolic, the problem is now down to the printed representation - maybe this, or something not unlike it, is more along the lines of what you're seeking...
        use warnings; use strict; use Data::Dumper; my %Diag; while (<DATA>) { my ($name, $val) = split; push @{ $Diag{$name} }, $val; } print "$_ => " . join(' ', @{$Diag{$_}}) . "\n" for keys %Diag; __DATA__ Name1 1234 Name2 9999 Name1 5514 Name3 5415 Name2 6419

        A user level that continues to overstate my experience :-))

        Have you run toolic's code? It does exactly what you desire.

Re: Hashes of arrays populated from a Text File
by Tux (Canon) on Feb 26, 2014 at 17:52 UTC

    Just for the alternative, splitting on TAB triggers me to mention Text::CSV_XS (using toolic's hash approach):

    use strict; use warnings; use Text::CSV_XS; my $csv = Text::CSV_XS->new ({ sep_char => "\t", auto_diag => 1 }); my %Diag; while (my $row = $csv->getline (*DATA)) { push @{$Diag{$row->[0]}}, $row->[1]; } $csv->eol ("\n"); $csv->sep_char (","); $csv->print (*STDOUT, [ $_, @{$Diag{$_}} ]) for sort keys %Diag; __DATA__ Name1 1234 Name2 9999 Name1 5514 Name3 5415 Name2 6419

    -->

    Name1,1234,5514 Name2,9999,6419 Name3,5415

    Enjoy, Have FUN! H.Merijn
Re: Hashes of arrays populated from a Text File
by sundialsvc4 (Abbot) on Feb 26, 2014 at 15:38 UTC

    Quite frankly, what I would do is to grab a copy of SQLite ... a public-domain SQL system that doesn’t use any kind of server ... and import all these files into a database, then use SQL queries to JOIN among the various tables to get the answers that you want.   You don’t have to write-a-program to import the data.

    Also, if this happens to be a one-off task, consider the ubiquitous spreadsheet ... which will also certainly have the capability to obtain data from a database file and even to perform queries against it.   (Or do vlookup() and so-on.)

    I’m just suggesting ... look at the target and all of the potential ways of hitting that target.   Sure, “writing a Perl program” is one way to do it.   Perl can do it effortlessly and other posts on this thread will show you exactly how.   But if what you have is a bunch of CSV files, and what you want to get is a result that can be described as joining data between them, then in all likelihood you do not need to “write a program” to do that.

      You must be kidding, sundialsvc4. Using a database for such a simple task is just plain overkill. You can obtain the desired result with just a simple Perl one-liner:
      $ cat test_file.txt Name1 1234 Name2 9999 Name1 5514 Name3 5415 Name2 6419 $ perl -ne 'my ($key, $val) = split; $hash{$key} .= " $val"; END { pri +nt "$_ => $hash{$_} \n" for keys %hash;}' test_file.txt Name3 => 5415 Name1 => 1234 5514 Name2 => 9999 6419
      The result is there even before you start populating your database.

      Up-voted because of the hilarious nature of the overkill (and huge amount of work involved) in avoiding writing a one-line perl script

      That sounds awesome, and I have heard good things, unfortunately, my work won't give me approval to download it. So, I can't do that, but I have looked into it. Thank you for your suggestion.

        "...my work won't give me approval to download it...

        Do you mean the company you are with doesn't permit that you use some code you got from PM or elsewhere? But why?

        Regards, Karl

        «The Crux of the Biscuit is the Apostrophe»

Log In?
Username:
Password:

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

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

    No recent polls found