3

I have an array where elements of the array have values that are separated by tabs. For example:

client_name \t owner \t date \t port_number.

I need to convert that into a hash so it can be dumped into a MySQL database. Something like:

my %foo = ();
$foo{date} = "111208";
$foo{port} = "2222";
$foo{owner} = "ownername";
$foo{name} = "clientname";   

The problem I have is that there are duplicate client names but they exist on different port numbers. If I convert it directly to a hash using client_name as a key it will delete duplicate client names. The MySQL table is indexed based on {name} and {port}.

Is there any way I can convert this into a hash without losing duplicate client names?

3 Answers 3

4

You would go through your file, build up the hash like you've done, then push a reference to that hash onto an array. Something like:

foreach my $line ( @lines ) {
  # Make your %foo hash.
  push @clients, \%foo;
}

Then afterwards, when you're inserting into your DB, you just iterate through the elements in @clients:

foreach my $client ( @clients ) {
  $date = $client->{'date'};
  ...
}

Edit: If you want to turn this into a hash of hashes, then as you loop through the list of lines, you'd do something like:

foreach my $line ( @lines ) {
  # Make your %foo hash.
  $clients{$foo{'port'}} = \%foo;
}

Then you'll have a hash of hashes using the port number as the key.

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

2 Comments

I have a module that uses a hash to insert into the database, so I wanted to keep it as a hash. One thought I had would be to create a hash of hashes that uses the port number as the key.
@cottageDog: There are endless ways of putting your data into a hash, but everything depends on what form your module requires the hash to be in. Is this module a public one with documenation we can read? Or can you give us an example of a database insertion using it?
1

Why not just store it in a list (array)?

my @records = ();
while (my $line = <INFILE>) {
  chomp $line;
  my @fields = split /\t/ $line;
  push @records => { date => $fields[2],
                     name => $fields[0],
                     port => $fields[3],
                     owner => $fields[1] };
}
for my $record (@records) {
   $insert_query->execute (%$record);
}

Comments

0
my @record_list;
while ( <$generic_input> ) { 
     my $foo = {};
     @$foo{ qw<date port owner name> } = split /\t/;
     push @record_list, \%foo;
 }

As a "pipeline" you could do this:

use List::MoreUtils qw<pairwise>;
my @fields = qw<date port owner name>;
my @records 
    = map {; { pairwise { $a => $b } @fields, @{[ split /\t/ ]}}}
      <$input>
    ;

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.