perl: sprintf for element in list



我对此感到非常困惑,我正在尝试创建一个大的数字矩阵,我想将sprintf与perl一起使用以获得更好的输出。我正在尝试使用这样的sprintf

my $x = 0;
my $y = 0;
for ($x=1; $x<=$steps; $y++) { # loop through lines
for ($y=0; $y<=$distances; $y++) { 
my $format = sprintf ("%s",$matrix[$x][$y]);

但这确实让我很费脑筋,因为我正在循环遍历$x和$y的所有值并得到它们的组合。所以我不确定我是否打算使用更多这样的格式参数

my $format = sprintf ("%s%s%s",$matrix[$x][$y]);

(当然,这给了我编译错误,因为它是不对的)

但是当我只使用一个参数时,我不能在我的列之间放置空格:/有人可以解释一下发生了什么吗?我真的不明白我应该怎么做才能使格式变得漂亮。我希望只对齐列并在它们之间有几个空格。非常感谢大家。

我会考虑使用 map ,作为显示每个元素的一种方式:

#!/usr/bin/env perl
use strict;
use warnings;
my @matrix = ( [1,2,3,4],
               [5,6,7,8], 
               [9,10,11,12], );
 print join ("n", map { join ( "t", @$_ ) } @matrix ); 

这是在制表位上格式化的,而不是固定宽度的列,并输出:

1   2   3   4
5   6   7   8
9   10  11  12

如果你特别想要sprintf

foreach my $row ( @matrix ) { 
   print map { sprintf("%5s", $_) } @$row,"n";
}

(5列宽)。

在每行中,我都在处理整行 - 这只真正适用,如果我对你显示的元素所做的假设是正确的。

在非常基本的级别 - 您的代码可以工作为:

#!/usr/bin/env perl
use strict;
use warnings;
my @matrix    = ( [ 1, 2, 3, 4 ], 
                  [ 5, 6, 7, 8 ], 
                  [ 9, 10, 11, 12 ], );
my $steps     = 2;
my $distances = 3;
for ( my $x = 1; $x <= $steps; $x++ ) {    # loop through lines
    for ( my $y = 0; $y <= $distances; $y++ ) {
        printf( "%5s", $matrix[$x][$y] );
    }
    print "n";
}

虽然注意 - 这仅适用于相同数量的列。但是,您可以执行以下操作:

#!/usr/bin/env perl
use strict;
use warnings;
my @matrix    = ( [ 1, 2, ], 
                  [ 3, 4, 5,  ], 
                  [ 6, 7, 8, 9, 10, 11, 12 ], );
my $steps     = 2;
my $distances = 3;
for ( my $x = 1; $x <= $steps; $x++ ) {    # loop through lines
    for ( my $y = 0; $y <= $distances; $y++ ) {
        printf( "%5s", $matrix[$x][$y] // '' );
    }
    print "n";
}

这会省略第一行(因为您将$x设置为 1),并最多迭代 4 列:

3    4    5     
6    7    8    9

这将省略最后一行的额外值,并使用//来测试单元格是否为空。

for my $row (@matrix) {
   my $format = join(' ', ('%5.2f') x @$row)."n";
   printf($format, @$row);
}

如果所有行的列数相同,则可以计算一次格式。

if (@matrix) {
   my $format = join(' ', ('%5.2f') x @{$matrix[0]})."n";
   for my $row (@matrix) {
      printf($format, @$row);
   }
}

如果列的大小事先不是未知的,则需要按顺序执行以下操作:

  1. 格式化单元格(如果需要),
  2. 找到每列最大单元格的长度,然后
  3. 打印出带有填充的矩阵。

下面假设矩阵的每一行长度相同。

use List::Util qw( max );
if (@matrix) {
   for my $row (@matrix) {
      $_ = sprinf('%.2f', $_) for @$row;
   }
   my $num_cols = @{$matrix[0]};
   my @col_sizes = (0) x $num_cols;
   for my $row (@matrix) {
      $col_sizes[$x] = max(0, $col_sizes[$x], $row->[$x]);
   }
   my $format = join(' ', map { "%$_s" } @col_sizes)."n";
   for my $row (@matrix) {
      printf($format, @$row);
   }
}

最新更新