Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Hash of Array references

by sravs448 (Acolyte)
on Aug 04, 2014 at 14:11 UTC ( [id://1096127]=perlquestion: print w/replies, xml ) Need Help??

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

I have a perl program which generates me 3 outputs, 1) Number 2)user 3) comments. I would like to associate a specific number with respective user and comments. How do I display the user and comments when someone enters the number?

use strict; use Data::Dumper; #Header printf "%-12s %-10s %s\n", qw(Number User Comments); $result =`cmd to get the result`; #Formatting the output while ($result =~ /number (\d+).*user:\s*(\S+)\s*#\s*(.*)/g) { printf "%-12s %-10s %s\n", $1, $2, $3; #Pushing the result from variables to 3 Arrays push @numbers, $1; push @users , $2; push @comments, $3; } #References to Array my $numbers_ref = \@numbers; my $users_ref = \@users; my $comments_ref = \@comments; #Hash of array references my %hash = ( )

The current output from the print statement looks like this. But I would like to display "sam"and "changed abc in the file", when some enters number as "1234567"

Number User Comments 1234567 sam changed abc in the file. 5646542 john deleted asds in the file.

Replies are listed 'Best First'.
Re: Hash of Array references
by choroba (Cardinal) on Aug 04, 2014 at 14:18 UTC
    I'd create a hash where the number is the key and each value is an array (reference) than contains the user and the comments.
    #!/usr/bin/perl use warnings; use strict; #Header printf "%-12s %-10s %s\n", qw(Number User Comments); my $result =`cmd to get the result`; my %users; while ($result =~ /number (\d+).*user:\s*(\S+)\s*#\s*(.*)/g) { my ($number, $user, $comment) = ($1, $2, $3); printf "%-12s %-10s %s\n", $number, $user, $comment; $users{$number} = [ $user, $comment ]; } print 'Select a number: '; my $input = <STDIN>; chomp $input; if (exists $users{$input}) { print "@{ $users{$input} }\n"; } else { print "Unknown number.\n"; }

    Update: Fixed typos in the code after testing it.

    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

      It worked great. But how can I access the respective $user and $comments independetly?

      print 'Select a number: '; my $input = <STDIN>; chomp $input; if (exists $users{$input}) { print "Number entered is : $users{$input} \n"; print "User for the number $users{$input} is : \n"; print "Comments for the number $users{input} is : \n"; } else { print "Unknown number.\n"; }

      Something like this in the output

      Number entered is : 12345678 User for number 123456789 is : Sam Comments for the number 123456789 is : Changed "abc" in the file
Re: Hash of Array references
by AppleFritter (Vicar) on Aug 04, 2014 at 14:18 UTC

    I'd suggest using a hash of hashes for your data:

    #!/usr/bin/perl use strict; use warnings; use feature qw/say/; my $result = q/ number 1234567 user: sam # changed abc in the file. number 5646542 user: john # deleted asds in the file. /; my %parsed_results = (); while($result =~ /number (\d+).*user:\s*(\S+)\s*#\s*(.*)/g) { $parsed_results{$1} = { 'user' => $2, 'comment' => $3, } } print "Enter a number: "; chomp(my $number = <STDIN>); if(exists $parsed_results{$number}) { say "User : ", $parsed_results{$number}->{'user'}; say "Comment: ", $parsed_results{$number}->{'comment'}; } else { say "Not found: $number"; }
Re: Hash of Array references
by MidLifeXis (Monsignor) on Aug 04, 2014 at 14:27 UTC

    Can numbers be repeated? Is a single user always associated with a single number (UID), or can multiple (users|numbers) be associated with a single (number|user)?

    --MidLifeXis

      The numbers are unique.They wont be duplicated. An a number will have only ONE user and comment associated to it

Re: Hash of Array references
by McA (Priest) on Aug 04, 2014 at 14:25 UTC

    Hi,

    This should give you a starting point:

    #!/usr/bin/perl use strict; use warnings; use 5.010; use Carp; use Data::Dumper; use strict; use Data::Dumper; my %hash; while(my $line = <DATA>) { chomp $line; next if $line =~ m/^\s*#/; next if $line =~ m/^\s*$/; my ($number, $user, $comment) = split /\s+/, $line, 3; $hash{$number} = { number => $number, user => $user, comment => $comment, } } say Dumper(\%hash), "\n"; __DATA__ #Number User Comments 1234567 sam changed abc in the file. 5646542 john deleted asds in the file. 45656 me what a use name 535353 McA Supermonk *grin*

    UPDATE: MidLifeXis had a very good question at Re: Hash of Array references. If you want to allow more than one entry per number you can collect them in an array. So change the lines

    $hash{$number} = { number => $number, user => $user, comment => $comment, }

    to

    push @{$hash{$number}}, { number => $number, user => $user, comment => $comment, };

    Regards
    McA

Re: Hash of Array references
by sundialsvc4 (Abbot) on Aug 04, 2014 at 14:38 UTC

    I prefer to think of data-structures like this as complex ”records” that might be “indexed” in a number of different ways.   For example, define a single (anonymous) hashref to be your “record,” with a key for each “field” and a value that consists, as the case may be, either of a scalar or an array of values.   Your basic data store is an array of those hashrefs.

    Then, for all of the ways that I need to locate those records ... well, here you have a pragmatic choice.

    One way is to use additional hashes as indexes:   the keys are values being sought, and the values are either a single scalars (references are scalars), or an array of references.   You look up the key, then you have a reference to the record(s) that match that key.

    But, pragmatically, you can also often just-as-well use the grep function to loop through the entire array, brute-force.   It is memory, after all, albeit virtual, but if you have “gobs of RAM,” it’s usually fast-enough just to search for whatever you want each time.

    Still, when it comes down to locating “a record,” I do eventually want to come to that:   a single data-structure (a hashref), which, by itself and self-contained, contains all of whatever I need to know about that Thing.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (4)
As of 2024-04-24 07:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found