Reputation: 1
I'm trying to write a function that will read a delimited file (think something like /etc/passwd) and return the values in a hash. The delimiter, column names and key columns will be specified as parameters to the function, the last two passed as array references. It will return a reference to a hash.
I'd like to allow both single and compound keys, but I can't figure out the best way to create the hash when I don't know the depth of the keys beforehand.
For example, suppose I specify 4 columns: A, B, C, and D, and two key columns: A and D. To assign values from a single line in the file, we'd have something like:
$var->{A value)->{D value)->{A} = A value;
$var->{A value)->{D value)->{B} = B value;
...
However, if I specify only a single key column (B), it would look like:
$var->{B value)->{A} = A value;
$var->{B value)->{B} = B value;
...
What would be a way to generalize this without knowing the number of key columns prior to execution?
Upvotes: 0
Views: 89
Reputation: 385809
use Data::Diver qw( DiveVal );
my @key_col_names = ...;
my @col_names = ...;
my $data;
while ( my @row = ... ) {
my %rec; @rec{@col_names} = @row;
my @keys = @rec{@key_col_names};
DiveVal($data, map \$_, @keys) = \%rec;
}
You can use the following instead of DiveVal($data, map \$_, @keys) = \%rec
:
sub dive_val :lvalue {
my $p = \shift;
$p = \( $$p->{$_} ) for @_;
$$p
}
dive_val($data, @keys) = \%rec;
Upvotes: 1