http://www.perlmonks.org?node_id=1023885

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

Hi PerlMonks,

I am interested to access the data for a student using the query of Registration number. I have no idea about making a database. So I have thought of using the arrays to get the detailed information. Is it possible to get the desired results using arrays and hash as given in the following script (incomplete)? I request Perlmonks to provide some suggestions in this matter.

#!/usr/bin/perl use warnings; use strict; ################################# ## HASH OF ARRAYS: ################################# my @a=qw/A B C D/; my @b=qw/20 19 22 23/; my @c=qw/x1 x2 x3 x4/; my @d=qw/phone4 phone2 phone3 phone1/; my @e=qw/72 55 83 69/; my @f=qw/2011 2012 2009 2008/; # HASH of arrays: my %hash=('Name' => @a, 'Age' => @b, 'Regd_no' => @c, 'Phone_num'=> @d, 'Marks' => @e, 'Pass_year'=> @f); ## To access all the information with the query of Regd Number: print"\n Enter the regd number (say x3): "; my $entry=<STDIN>; ## Code for accessing individual student information ??? (Not known) ## Code for inserting & deleting the details of a student ??? exit;

Result should look like:

Regd No. x3 has the following details:

Name: C

Age : 22

Phone_num: phone3

Marks: 83

Pass_Year: 2009

  • Comment on How can one access all the details of a person using arrays & hash?
  • Download Code

Replies are listed 'Best First'.
Re: How can one access all the details of a person using arrays & hash?
by Athanasius (Archbishop) on Mar 17, 2013 at 07:28 UTC

    Distributing the data for a single student across multiple arrays is asking for trouble. Much better to keep each student’s data in the same structure. So I would reverse the architecture: instead of a hash of arrays, use an array of hashes. Or, more precisely, an array of blessed hashes (objects). Something like this:

    #! perl use strict; use warnings; { package Student; sub new { my ($class, $name, $age, $regd_no, $phone_num, $mark, $pass_year) = @_; my $self = { NAME => $name, AGE => $age, REGD_NO => $regd_no, PHONE_NUM => $phone_num, MARK => $mark, PASS_YEAR => $pass_year }; return bless $self, $class; } sub display { my ($self) = @_; if ($self) { print 'Name: ', $self->{NAME}, "\n"; print 'Age: ', $self->{AGE}, "\n"; print 'Regd no: ', $self->{REGD_NO}, "\n"; print 'Phone num: ', $self->{PHONE_NUM}, "\n"; print 'Mark: ', $self->{MARK}, "\n"; print 'Pass year: ', $self->{PASS_YEAR}, "\n"; } } } my @students; while (<DATA>) { chomp; push @students, Student->new(split /:/); } find_student('x3')->display(); sub find_student { my ($regd_no) = @_; for (@students) { return $_ if $_->{REGD_NO} eq $regd_no; } return undef; } __DATA__ A:20:x1:phone4:72:2011 B:19:x2:phone2:55:2012 C:22:x3:phone3:83:2009 D:23:x4:phone1:69:2008

    Output:

    17:18 >perl 578_SoPW.pl Name: C Age: 22 Regd no: x3 Phone num: phone3 Mark: 83 Pass year: 2009 17:22 >

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      Hi Athanasius,

      Thanks for your prompt reply. I shall try to understand the code given by you. Should I find any difficulty, I shall let you know.

      With deep regards,

Re: How can one access all the details of a person using arrays & hash?
by CountZero (Bishop) on Mar 17, 2013 at 08:54 UTC
    I have no idea about making a database.
    Like it or not, even your array of hashrefs or hash of arrayrefs are the building blocks of a database. But rather than stumble in the dark and (badly) re-invent databases, spend some time studying database design and theory. It is knowledge that will pay itself back over and over again. This Wikiversity link is not a bad place to start.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

    My blog: Imperial Deltronics
Re: How can one access all the details of a person using arrays & hash?
by topher (Scribe) on Mar 17, 2013 at 07:31 UTC

    For a case like this, I probably wouldn't use arrays. I'd use a Hash of Hashes for the students. The outer hash would key on the registration number, with its value being a second hash that contains the student details. That'll give you a more self-documenting data structure that allows direct access to any student by registration number.

    If I was going to use arrays somewhere, I would recommend strongly against using them the way you are. Not to be mean, but the data structure as you have it written is probably the worst way to do it. You don't want to split up related data across multiple data structures (in your case, multiple arrays). You'd be better off using an array of arrays (or hashes), assuming you were always going to "process" all student entries every time. Or, use a hash of arrays, using the array to hold the details for each individual student, and hashing on the registration number.

    Here's an example of using the Hash of Hashes I described above:

    #!/usr/bin/env perl use strict; use warnings; my %students; my $key = shift || 0; while (<DATA>) { chomp; my ( $name, $age, $reg_no, $phone, $marks, $year ) = split ":"; $students{$reg_no} = { name => $name, age => $age, phone => $phone, marks => $marks, year => $year, }; } if ($key) { # Print the details of our preselected student print "Information for student with registration number $key is: \ +n"; print " Name: " . $students{$key}{name} . "\n"; print " Age: " . $students{$key}{age} . "\n"; print " Phone: " . $students{$key}{phone} . "\n"; print " Marks: " . $students{$key}{marks} . "\n"; print " Year: " . $students{$key}{year} . "\n"; } else { # Print the name for each student we have a record for print "List of all students:\n"; foreach my $id ( sort keys %students ) { print " Registration Number: " . $id . "\n"; print " Name: " . $students{$id}{name} . "\n"; } } __DATA__ John Doe:20:x1:555-1234:50:2013 Jane Doe:19:x2:555-4321:55:2012 Bob Smith:22:x3:555-2468:90:2011 Mortimer Jones:18:x4:555-0313:77:2008

    And some sample outputs of running the above code:

    topher@nexus:~/foo$ ./student-HoH.pl List of all students: Registration Number: x1 Name: John Doe Registration Number: x2 Name: Jane Doe Registration Number: x3 Name: Bob Smith Registration Number: x4 Name: Mortimer Jones topher@nexus:~/foo$ ./student-HoH.pl x4 Information for student with registration number x4 is: Name: Mortimer Jones Age: 18 Phone: 555-0313 Marks: 77 Year: 2008

    Christopher Cashell