データベーステーブルをSTDOUTに出力したいと思います。min_width
テーブル幅が画面幅よりも大きい場合は、テーブルが画面に収まるまで、(テーブル幅に達していない限り)同じパーセンテージで列をそれぞれ切り取りたいと思います。私は投稿されたサブルーチンでこれを解決しようとしました。誰かがこの問題を解決するためのより短くてより洗練されたアルゴリズムを知っていますか?
sub cal_size {
my ( $maxcols, $ref ) = @_;
# $maxcols => screen width
# $ref => ref to an AoA; holds the table
my ( $max ) = cal_tab( $ref );
# $max => ref to an array; holds the length of the longest string of each column
# $tab = 2;
if ( $max and @$max ) {
my $sum = sum( @$max ) + $tab * @$max;
$sum -= $tab;
my @max_tmp = @$max;
my $percent = 0;
while ( $sum > $maxcols ) {
$percent += 0.5;
if ( $percent > 99 ) {
return;
}
my $count = 0;
for my $i ( 0 .. $#max_tmp ) {
# $min_width => columns width should not be less than $min_width if possible
next if $min_width >= $max_tmp[$i];
# no need to cut if the column width id less than min_width
next if $min_width >= minus_x_percent( $max_tmp[$i], $percent );
# don't cut if column width become less than min_width
$max_tmp[$i] = minus_x_percent( $max_tmp[$i], $percent );
$count++;
last if $sum <= $maxcols;
}
$min_width-- if $count == 0 and $min_width > 1;
# if no cuts but $sum > $maxcols reduce $min_width
$sum = sum( @max_tmp ) + $tab * @max_tmp;
$sum -= $tab;
}
my $rest = $maxcols - $sum;
while ( $rest > 0 ) { # distribute the rest
my $count = 0;
for my $i ( 0 .. $#max_tmp ) {
if ( $max_tmp[$i] < $max->[$i] ) {
$max_tmp[$i]++;
$rest--;
$count++;
last if $rest < 1;
}
}
last if $count == 0;
last if $rest < 1;
}
$max = [ @max_tmp ] if @max_tmp;
}
return $max;
}
sub minus_x_percent {
my ( $value, $percent ) = @_;
return int $value - ( $value * 1/100 * $percent );
}