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

populating a HoA with regexp

by asqwerty (Acolyte)
on Aug 28, 2012 at 13:45 UTC ( #990249=perlquestion: print w/replies, xml ) Need Help??
asqwerty has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks,

I have a file with a single column of words like this:

brain0001 lung0001 brain00002 kidney0003 brain00003

I need to put this words into a hash of arrays, separated by its category (brain, lung, kidney), so I wrote this code:

$data = "mydata.list"; @pref = ("brain", "lung", "kidney"); %dfs = map {$_ => ()} @pref; open DF, "<$data"; while(my $line=<DF>){ chomp($line); foreach $pat (@pref){ push @{$dfs{$pat}},$line if ($line=~/$pat/); } } close DF;

This code actually works and populate the hash in the right way. However, I think the foreach loop can be replaced with a single line.

How can I do this?

Replies are listed 'Best First'.
Re: populating a HoA with regexp
by BrowserUk (Pope) on Aug 28, 2012 at 13:55 UTC

    You could do this:

    #! perl -slw use strict; use Data::Dump qw[ pp ]; my %dfs; m[([a-z]+)(\d+)] and push @{ $dfs{ $1 } }, $2 while <DATA>; pp \%dfs; __DATA__ brain0001 lung0001 brain00002 kidney0003 brain00003


    [14:52:38.81] C:\test>junk58 { brain => ["0001", "00002", "00003"], kidney => ["0003"], lung => ["0001"], }

    But maybe you don't want to load up anything you are not expecting? Maybe you want a warning for lines that don;t match your regex?

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

    RIP Neil Armstrong



      Actually I want to load only the words I'm expecting, but your answer (and the previous reply) gave me the hint I need

Re: populating a HoA with regexp
by Athanasius (Chancellor) on Aug 28, 2012 at 15:06 UTC

    Hello asqwerty, and welcome to the Monastery!

    You already have the answer you were looking for. I just want to point out that the line:

    %dfs = map {$_ => ()} @pref;

    is incorrect. You can see this by printing the contents of %dfs (using Data::Dumper) immediately after that line:

    $VAR1 = { 'brain' => 'lung', 'kidney' => undef };

    When interpolated into an array or hash, the empty list () effectively disappears. I think you meant to write:

    %dfs = map {$_ => []} @pref;

    which works correctly, although

    %dfs = map {$_ => undef} @pref;

    also works.

    Here is some good advice: Get into the habit of including the lines

    use strict; use warnings;

    at the head of every script. In this case, warnings would have shown you the problem:

    Odd number of elements in hash assignment at ... line 6.

    Hope that helps,

    Athanasius <°(((><contra mundum

      Thanks a lot!

      As you point out my code was wrong.

Re: populating a HoA with regexp
by Anonymous Monk on Aug 28, 2012 at 13:50 UTC

    I call mine uiop

    #!/usr/bin/perl -- use strict; use warnings; use Data::Dump; open my($DF), '<', \q{ brain0001 lung0001 brain00002 kidney0003 brain00003 }; my %dfs; while( <$DF> ){ chomp; /^(brain|lung|kidney)/ and push @{$dfs{$1}}, $_; } close $DF; dd \%dfs; __END__ { brain => ["brain0001", "brain00002", "brain00003"], kidney => ["kidney0003"], lung => ["lung0001"], }
Re: populating a HoA with regexp
by linuxkid (Sexton) on Aug 28, 2012 at 20:44 UTC

    Readability should be valued over brevity/speed


      Quickly said--and with readable brevity! :)

      Readability should be valued over brevity/speed

      Learn to speak perl

      I think that

      /^($pattern)/ and push @{$dfs{$1}}, $_;

      is readable enough. Maybe even more readable (in a perl way) than my previous solution.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://990249]
Front-paged by Arunbear
[Corion]: A good morning, Discipulus!
[Discipulus]: are you sleppless 1nickt or you are in a tifferent TZ?

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (3)
As of 2017-10-20 06:50 GMT
Find Nodes?
    Voting Booth?
    My fridge is mostly full of:

    Results (259 votes). Check out past polls.