3

I am having some problem with my perl. I hashed a key to an array. Now I want to change things in the array for each key. But I can't find out how this works :

open(DATEBOOK,"<sample.file");

@datebook = <DATEBOOK>;

$person = "Norma";

foreach(@datebook){
    @record = ();
    @lines = split(":",$_);

        $size = @lines;
        for ($i=1; $i < $size; $i++){
            $record[$i-1] = $lines[$i];
        }
    $map{$lines[0]}="@record";  

}

for(keys%map){ print $map{$_}};

The datebook file :

Tommy Savage:408.724.0140:1222 Oxbow Court, Sunnyvale,CA 94087:5/19/66:34200
Lesle Kerstin:408.456.1234:4 Harvard Square, Boston, MA 02133:4/22/62:52600
JonDeLoach:408.253.3122:123 Park St., San Jose, CA 94086:7/25/53:85100
Ephram Hardy:293.259.5395:235 Carlton Lane, Joliet, IL 73858:8/12/20:56700
Betty Boop:245.836.8357:635 Cutesy Lane, Hollywood, CA 91464:6/23/23:14500
William Kopf:846.836.2837:6937 Ware Road, Milton, PA 93756:9/21/46:43500
Norma Corder:397.857.2735:74 Pine Street, Dearborn, MI 23874:3/28/45:245700
James Ikeda:834.938.8376:23445 Aster Ave., Allentown, NJ 83745:12/1/38:45000
Lori Gortz:327.832.5728:3465 Mirlo Street, Peabody, MA 34756:10/2/65:35200
Barbara Kerz:385.573.8326:832 Ponce Drive, Gary, IN 83756:12/15/46:268500

I tried $map{$_}[1], but that doesn't work. Can anyone give me an example on how this works :) ?

thanks!

1
  • 1
    In first place : use strict; use warnings;. Then what is not working ? Commented Jun 15, 2011 at 12:57

2 Answers 2

4

First, use strict and use warnings. Always.

Assuming what you want is a hash of arrays, do something like this:

use strict;
use warnings;

open my $datebookfh, '<', 'sample.file' or die $!;
my @datebook = <$datebookfh>;

my %map;
foreach my $row( @datebook ) { 
    my @record = split /:/, $row;
    my $key = shift @record;   # throw out first element and save it in $key

    $map{$key} = \@record;
}

You can test that you have the correct structure by using Data::Dumper:

use Data::Dumper;
print Dumper( \%map );

The \ operator takes a reference. All hashes and arrays in Perl contain scalars, so compound structures (e.g. hashes of arrays) are really hashes of references to arrays. A reference is like a pointer.

Before going further, you should check out:

Sign up to request clarification or add additional context in comments.

2 Comments

I see what you mean, I read the reference tutorial now so my mistake was trying to add an array instead of scalar value to the hash. But when you make a reference to the array you actually point to where the array is stored in the memory ?
Lucas, yes, array references are special scalars which point to the original array's memory location. That means if you modify the original array, anything containing references to it will see the modification as well. If you need to avoid this, you can make a reference to a copy of the array by doing my $aref = [ @array ]; or for hashes, my $href = { %hash };
3

Others have given you excellent advice. Here's one other idea to consider: store your data in a hash of hashes rather than a hash of arrays. It makes the data structure more communicative.

# Include these in your Perl scripts.
use strict;
use warnings;

my %data;

# Use lexical files handles, and check whether open() succeeds.
open(my $fh, '<', shift) or die $!;

while (my $line = <$fh>){
    chomp $line;
    my ($name, $ss, $address, $date, $number) = split /:/, $line;
    $data{$name} = {
        name    => $name,
        ss      => $ss,
        address => $address,
        date    => $date,
        number  => $number,
    };
}

# Example usage: print info for one person.
my $person = $data{'Betty Boop'};
print $_, ' => ', $person->{$_}, "\n" for keys %$person;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.