perl:sprintf列表中的元素

时间:2016-02-17 16:03:46

标签: perl printf

我对此非常困惑,我正在尝试创建一个大数字矩阵,我想用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]);

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

但是当我只使用一个参数时,我不能在我的列之间添加空格:/有人可以解释发生了什么吗?我真的不明白我的目的是为了让格式化得更好。我希望只对齐列,并在它们之间有几个空格。非常感谢你们。

2 个答案:

答案 0 :(得分:0)

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. 用填充打印矩阵。
  4. 以下假设矩阵的每一行都是相同的长度。

    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);
       }
    }
    

答案 1 :(得分:0)

我会考虑使用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

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