App-td
view release on metacpan or search on metacpan
lib/App/td.pm view on Meta::CPAN
if ($n < 0) {
$output = [400, "Cannot tail negative number of rows"];
last;
} elsif ($n =~ s/\A\+//) {
splice @$rows, 0, $n-1 if $n >= 1;
} else {
splice @$rows, 0, @$rows - $n if $n < @$rows;
}
}
$output = [200, "OK", $rows, {'table.fields' => $cols}];
last;
}
if ($action eq 'colcount') {
$output = [200, "OK", $input_obj->col_count];
last;
}
if ($action eq 'colnames') {
my $cols = $input_obj->cols_by_idx;
my $colnames_row = [map {$cols->[$_]} 0..$#{$cols}];
$output = [200, "OK", $colnames_row];
last;
}
if ($action eq 'colnames-row') {
my $cols = $input_obj->cols_by_idx;
my $rows = $input_obj->rows;
my $colnames_row;
if (@$rows && ref $rows->[0] eq 'HASH') {
$colnames_row = $input_obj->cols_by_name;
} elsif (@$rows && ref $rows->[0] eq 'ARRAY') {
$colnames_row = [map {$cols->[$_]} 0..$#{$cols}];
} else {
$colnames_row = $cols->[0];
}
$output = [200, "OK", [@$rows, $colnames_row],
{'table.fields' => $cols}];
last;
}
if ($action eq 'rownum-col') {
$input_obj->add_col('_rownum', 0); # XXX if table already has that column, use _rownum2, ...
$input_obj->set_col_val(_rownum => sub { my %a = @_; $a{row_idx}+1 });
$output = [200, "OK", $input_obj->{data},
{'table.fields' => $input_obj->{cols_by_idx}}];
last;
}
if ($action =~ /\A(sum|sum-row|avg|avg-row)\z/) {
require Scalar::Util;
my $cols = $input_obj->cols_by_idx;
my $rows = $input_obj->rows;
# XXX optimize by not producing two versions of rows
my $rows_as_aoaos = $input_obj->rows_as_aoaos;
my $sums = [map {0} @$cols];
for my $i (0..$#{$rows_as_aoaos}) {
my $row = $rows_as_aoaos->[$i];
for my $j (0..@$cols-1) {
$sums->[$j] += $row->[$j]
if Scalar::Util::looks_like_number($row->[$j]);
}
}
my $avgs;
my $results;
if ($action =~ /avg/) {
if (@$rows) {
$avgs = [map { $_ / @$rows } @$sums];
} else {
$avgs = [map {0} @$cols];
}
$results = $avgs;
} else {
$results = $sums;
}
my $result_row;
if (@$rows && ref $rows->[0] eq 'HASH') {
$result_row = {map {$cols->[$_] => $results->[$_]}
0..$#{$cols}};
} elsif (@$rows && ref $rows->[0] eq 'ARRAY') {
$result_row = $results;
} else {
$result_row = $results->[0];
}
if ($action =~ /-row/) {
$output = [200, "OK", [@$rows, $result_row],
{'table.fields' => $cols}];
} else {
$output = [200, "OK", $result_row,
{'table.fields' => $cols}];
}
last;
}
if ($action eq 'shuf' || $action eq 'pick') {
my $cols = $input_obj->cols_by_idx;
my $input_rows = $input_obj->rows;
my $weight_column_idx = defined $args{weight_column} ?
$input_obj->col_idx($args{weight_column}) : undef;
my @output_rows;
if ($args{repeated}) {
if (defined $weight_column_idx) {
require Array::Sample::WeightedRandom;
my @ary = map { [$input_rows->[$_], $input_rows->[$_][$weight_column_idx]] } 0 .. scalar(@$input_rows);
@output_rows = Array::Sample::WeightedRandom::sample_weighted_random_with_replacement(\@ary, ($args{lines} // scalar(@$input_rows)));
} else {
for my $i (1 .. ($args{lines} // scalar(@$input_rows))) {
$output_rows[$i-1] = $input_rows->[rand() * @$input_rows];
}
}
} else {
if (defined $weight_column_idx) {
require Array::Sample::WeightedRandom;
my @ary = map { [$input_rows->[$_], $input_rows->[$_][$weight_column_idx]] } 0 .. scalar(@$input_rows);
@output_rows = Array::Sample::WeightedRandom::sample_weighted_random_no_replacement(\@ary, ($args{lines} // scalar(@$input_rows)));
} else {
require List::MoreUtils;
@output_rows = List::MoreUtils::samples(
$args{lines} // scalar(@$input_rows),
( run in 2.733 seconds using v1.01-cache-2.11-cpan-75ffa21a3d4 )