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


in reply to Data Structure Question

Your data could be stored in many ways. The key to choosing a data structure tends to relate to how you most often want to access it and how easy it is to write and maintain reliable code to manage it.

You could for example use an array of arrays - one entry per record where each record is an array containing three elements. That's good if you want to process all the data every time you perform a query, but is a maintenance nightmare if you ever need to change the number of fields in a record. Even just coding in the first place can be nasty unless you use named constants to access the individual elements in a record.

You could use an array of hashes which has most of the advantages of the AOA above, but provides named access to the fields in the records making coding and maintenance easier at the cost of needing more memory for storing the data.

If you need to access the data by some key field then a HOA or HOH is appropriate.

If you need to access the data by more than one key or there is more data than you really want to fit into memory, then you should use a database. That can actually be a lot simpler than you might think. Consider:

use strict; use warnings; use DBI; unlink 'db.SQLite'; # Build the database my $dbh = DBI->connect ("dbi:SQLite:dbname=db.SQLite","",""); $dbh->do ('CREATE TABLE employees (employee TEXT, form TEXT, date TEXT +)'); my $sth = $dbh->prepare ('INSERT INTO employees (employee, form, date) + VALUES (?, ?, ?)'); $sth->execute (do {chomp; split}) while <DATA>; print "Access by employee\n"; $sth = $dbh->prepare ( 'SELECT * FROM employees ORDER BY employee, form, date' ); $sth->execute (); my $employee = ''; while (my $row = $sth->fetchrow_hashref ()) { if ($employee ne $row->{employee}) { $employee = $row->{employee}; print "$employee\n"; } printf " %-6s %s\n", @{$row}{qw(form date)}; } print "Access by form\n"; $sth = $dbh->prepare ( 'SELECT * FROM employees ORDER BY form, employee, date' ); $sth->execute (); my $form = ''; while (my $row = $sth->fetchrow_hashref ()) { if ($form ne $row->{form}) { $form = $row->{form}; print "$form\n"; } printf " %-8s %s\n", @{$row}{qw(employee date)}; } __DATA__ 10001 10 20090101 10002 10 20080515 10003 10 20090323 10001 20 20090412 10002 20 20090711

Prints:

Access by employee 10001 10 20090101 20 20090412 10002 10 20080515 20 20090711 10003 10 20090323 access by form 10 10001 20090101 10002 20080515 10003 20090323 20 10001 20090412 10002 20090711

True laziness is hard work