例子。
如果输入是
输出应该是
因此,如果原始未排序的列没有这样的字符串,则每一行必须仅包含相同的值或 undef
。列中的值应按字母顺序排序。
如何实现这种排序?
附言原始任务 - 我们有一些模块,我们想在视觉上比较它们的名称相似的函数。
最佳答案
也许是这样的?
use warnings;
use strict;
my @data = (
{ name => 'Foo', funcs => [qw/abc def ghi xyz/] },
{ name => 'Bar', funcs => [qw/def jkl mno uvw xyz/] },
{ name => 'Baz', funcs => [qw/abc uvw xyz/] },
);
my %allfuncs = ( map { map {$_=>undef} @{$$_{funcs}} } @data );
$$_{funcs} = { %allfuncs, map {$_=>1} @{$$_{funcs}} } for @data;
use Data::Dump;
dd @data;
# just for output:
use List::Util qw/max/;
my $maxlen = max map {length} map({$$_{name}} @data), keys(%allfuncs);
my $fmt = join(' ', ("%${maxlen}s") x @data)."\n";
printf $fmt, map { $$_{name} } @data;
for my $f (sort keys %allfuncs) {
printf $fmt, map { $$_{funcs}{$f}?$f:'' } @data;
}
输出:
(
{
funcs => { abc => 1, def => 1, ghi => 1, jkl => undef, mno => undef, uvw => undef, xyz => 1 },
name => "Foo",
},
{
funcs => { abc => undef, def => 1, ghi => undef, jkl => 1, mno => 1, uvw => 1, xyz => 1 },
name => "Bar",
},
{
funcs => { abc => 1, def => undef, ghi => undef, jkl => undef, mno => undef, uvw => 1, xyz => 1 },
name => "Baz",
},
)
Foo Bar Baz
abc abc
def def
ghi
jkl
mno
uvw uvw
xyz xyz xyz
更新:如果您的输入数据以 AoA 的形式出现,这需要 @table
并生成与上面相同的 @data
(它基本上是转置 AoA,然后生成哈希结构):
my @table = ( [qw/Foo Bar Baz/], [qw/abc def abc/], [qw/def jkl uvw/],
[qw/ghi mno xyz/], [qw/xyz uvw/], [undef, qw/xyz/] );
my @data;
for my $col ( 0 .. $table[0]->$#* )
{ push @data, [ map {$_->[$col]//()} @table ] }
@data = map { {name=>shift @$_, funcs=>$_} } @data;
如果您也需要输出格式为 AoA:
my @out = ( [map {$$_{name}} @data] );
for my $f (sort keys %allfuncs)
{ push @out, [ map {$$_{funcs}{$f}?$f:undef} @data ] }
产生@out
:
(
["Foo", "Bar", "Baz"],
["abc", undef, "abc"],
["def", "def", undef],
["ghi", undef, undef],
[undef, "jkl", undef],
[undef, "mno", undef],
[undef, "uvw", "uvw"],
["xyz", "xyz", "xyz"],
)
关于algorithm - 按列中的相同值对表(或二维数组)进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54333145/