清理将阵列拆分为三分之一并显示给用户的方法

时间:2013-10-17 02:14:00

标签: arrays perl

我在perl脚本中有一个排序数组,例如:

qw(aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk lll)

是否有一种简单的方法可以将它显示在三列中,以便

  1. 前三分之一在左栏
  2. 中间三分之一在中间栏目
  3. ,最后三分之一在右栏
  4. 这样可以显示元素在屏幕上运行而不是在屏幕上运行。例如

    aaa eee iii
    bbb fff jjj
    ccc ggg kkk
    ddd hhh lll
    

    我一直在努力使用模数,但它变得越来越复杂,并认为可能有一个优雅的解决方案。最终我打算在bash中使用类似于select的东西。

    谢谢。

6 个答案:

答案 0 :(得分:8)

use List::MoreUtils qw( part );
my $num_rows = int(@a/3);
my @aoa = map [ @a[@$_] ], part { $_ % $num_rows } 0..$#a;
print("@$_\n") for @aoa;

use List::MoreUtils qw( part );
my $num_rows = int(@a/3);
my @aoa = part { $_ % $num_rows } 0..$#a;
print("@a[ @$_ ]\n") for @aoa;

my $num_rows = int(@a/3);
for my $row_num (0..$num_rows-1) {
   print("@a[ map { $row_num + $num_rows*$_ } 0..2 ]\n");
}

上述版本不假定@a%3 == 0。

use List::MoreUtils qw( part );
use POSIX           qw( ceil );
my $num_rows = ceil(@a/3);
my @aoa = map [ @a[@$_] ], part { $_ % $num_rows } 0..$#a;
print("@$_\n") for @aoa;

use List::MoreUtils qw( part );
use POSIX           qw( ceil );
my $num_rows = ceil(@a/3);
my @aoa = part { $_ % $num_rows } 0..$#a;
print("@a[ @$_ ]\n") for @aoa;

use POSIX qw( ceil );
my $num_rows = ceil(@a/3);
for my $row_num (0..$num_rows-1) {
   print("@a[ grep { $_ < @a } map { $row_num + $num_rows*$_ } 0..2 ]\n");
}

答案 1 :(得分:4)

在阅读完这个问题后,它看起来很像我在example的文档中读到的Perl6::Form。 (这是Perl5的实现)

use strict;
use warnings;
use Perl6::Form;

my @array = qw'aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk lll';

print form
  "{[[[[[:} {:[[[[:} {:[[[[[}",
  \@array,  \@array, \@array;
aaa      eee      iii
bbb      fff      jjj
ccc      ggg      kkk
ddd      hhh      lll

如果任何字符串的长度超过为其分配的长度,它就不会像你想要的那样工作。

...
$array[-1] .= ' lllllll';
...
aaa      fff      kkk
bbb      ggg      lll
ccc      hhh      lllllll
ddd      iii
eee      jjj

当然,您可以在调用form之前计算所需的宽度。

...

use List::Util qw'max';

my $max_length = max 5, map length, @array; # at least 5
my $TERMINAL_WIDTH = 80;
my $number_of_cols = int( $TERMINAL_WIDTH / ($max_length+1) );

my $single = '{:' . ( '[' x ($max_length-4) ) . ':} ';

print $single, "\n\n"; # debug statement

print form
  $single x $number_of_cols,
  (\@array) x $number_of_cols;
{:[[[[[[[:}

aaa         ccc         eee         ggg         iii         kkk
bbb         ddd         fff         hhh         jjj         lll lllllll
                                                                            80 ^

答案 2 :(得分:3)

这是我的解决方案,希望它可以帮到你。

use strict;
use warnings;

my @arr = ("aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk", "lll");
my $size = @arr;

my $column = 3;

my $mod = $size / $column;

my $i = $size;
my $count = 0;
while ($i > 0) {
    my $k = $count;
    while ($k < $size) {
        print "$arr[$k]\t";
        $k += $mod;
    }
    print "\n";
    $count++;
    $i -= $column;
}

答案 3 :(得分:3)

my @foo = qw(aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk lll);
my $rows = int( (@foo+2) / 3 );
my @row;
$row[$_ % $rows][$_ / $rows] = $foo[$_] for 0..$#foo;
for my $row (@row) {
    print join(' ', @$row), "\n";
}

答案 4 :(得分:2)

另一种选择:

use strict;
use warnings;

my @a = qw(aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk lll);
my @aoa;
push @{ $aoa[ $_ % 4 ] }, $a[$_] for 0 .. $#a;
print "@{ $_ }\n" for @aoa;

答案 5 :(得分:0)

4 LOC:非常简单......享受

 my @tokens = qw(aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk lll);
 my $text = join(" ",@tokens);
 while($text =~ /[^ ]+ [^ ]+ [^ ]+/g)
 {
     print "$&\n";
 }

萨米尔