Data-PcAxis
view release on metacpan or search on metacpan
lib/Data/PcAxis.pm view on Meta::CPAN
my $counts = $self->val_counts;
my $index;
for my $n (0..($#$selection - 1)) {
$index += $selection->[$n] * (reduce { $a * $b } @$counts[$n+1 .. $#$counts]);
}
$index += @$selection[-1];
my $res = $self->data->[$index];
$res =~ s/^["']|["']$//g; # Strip outer quotes from returned data
return $res;
}
sub datacol {
# TODO: Only allow one wildcard.
my $self = shift;
my $selection = shift;
my $counts = $self->val_counts;
my $datacol;
if ( any { $_ eq '*' } @$selection ) {
my $grp_idx = firstidx { $_ eq '*' } @$selection;
for my $i ( 0 .. (@$counts[$grp_idx] -1 )) {
$selection->[$grp_idx] = $i;
push @$datacol, $self->datum($selection);
}
}
else {
$datacol = $self->datum($selection);
}
return $datacol;
}
sub _build_metadata {
my $self = shift;
open my $fh, '<', $self->pxfile;
# slurp all metadata into one string, removing newlines
my $meta = '';
while (my $line = <$fh>) {
last if $line =~ /^DATA=/;
my $tmp = $meta;
$line =~ s/\R//g;
# double up end-of-line semicolons to solve problem of semicolons appearing within fields
$line =~ s/;$/;;/g;
$meta = $tmp . $line;
}
close $fh;
# join broken lines (e.g. TITLE="...Very Long"\n"Title")
$meta =~ s/""/ /g;
# split metadata string into array
my @meta = split ';;', $meta;
# initialise Text::CSV objects for parsing options and values
my $csv_opt = Text::CSV->new({binary=>1}) or die Text::CSV->error_diag();
my $csv_val = Text::CSV->new({binary=>1}) or die Text::CSV->error_diag();
# parse metadata array into a hash
my $metadata;
for my $i (0..$#meta) {
# Regex grabs key, option (optional value appearing after key in brackets, used
# to specify values to which this metadata key refers), and values from each
# metadata entry
my ($key, $opt, $val) = $meta[$i] =~ /^(?<key>.+?)(?:\((?<opt>.+?)\))?=(?<val>.+)$/;
# if entry has no 'option' value then data is specific to table
$opt //= 'TABLE';
# parse comma separated list of values to array
$csv_val->parse($val);
my @val_fields = $csv_val->fields();
# parse comma separated list of options to array
$csv_opt->parse($opt);
my @opt_fields = $csv_opt->fields();
# add array of values to appropriate key->option branch of metadata hash
for my $field (@opt_fields) {
if ($key ne 'VALUES') {
$metadata->{$key}->{$field} = scalar @val_fields == 1 ? $val_fields[0] : [ @val_fields ];
}
else {
# ensure that a single VALUES option still gets assigned to an array
$metadata->{$key}->{$field} = [ @val_fields ];
}
}
}
return $metadata;
}
sub _build_data {
my $self = shift;
open my $fh, '<', $self->pxfile;
my @data;
my $dataflag = 0;
DATAROW:
while (my $line = <$fh>) {
if ($line =~ /^DATA=/) {
$dataflag = 1;
}
next DATAROW unless $dataflag == 1;
chomp $line;
$line =~ s/DATA=//;
$line =~ s/;//;
my @row = split /\s+/, $line;
push @data, @row;
( run in 1.451 second using v1.01-cache-2.11-cpan-71847e10f99 )