Arrays 如何在Perl中按列对数组或表进行排序?

Arrays 如何在Perl中按列对数组或表进行排序?,arrays,string,perl,sorting,data-structures,Arrays,String,Perl,Sorting,Data Structures,我一直在到处寻找这个问题的答案,但我就是无法让它发挥作用 我有一个使用Perl读取到数组中的输入文件。该文件是一个包含表的文本文件。Perl将其作为数组读入,每个元素都是一整行(包括所有五列)。这就是阵列的外观: 0\uu len\uu 340 16 324 0.0470588235294118 1_uulen_uu251 2 249 0.00796812749003984 2_uuulen_uuuu497 0 3_uuulen_uuuu55 7 48 0 0.1272727 4_uuulen_

我一直在到处寻找这个问题的答案,但我就是无法让它发挥作用

我有一个使用Perl读取到数组中的输入文件。该文件是一个包含表的文本文件。Perl将其作为数组读入,每个元素都是一整行(包括所有五列)。这就是阵列的外观:

0\uu len\uu 340 16 324 0.0470588235294118
1_uulen_uu251 2 249 0.00796812749003984
2_uuulen_uuuu497 0
3_uuulen_uuuu55 7 48 0 0.1272727
4_uuulen_uuu171 0 171 0 0
5_uuulen_uuu75 0 0
6_uulen_u160 75 85 0 0.46875
7_uulen_uu285 1284 0.00350877192982456
8_uulen_u94 44 50 0 0.468085106382979
我需要按最后一列按降序对这个表进行排序。因此,我的输出应该是:

6_uulen_uu160 75 85 0.46875
8_uulen_u94 44 50 0 0.468085106382979
3_uuulen_uuuu55 7 48 0 0.1272727
0_uulen_u340 16 324 0.0470588235294118
1_uulen_uu251 2 249 0.00796812749003984
7_uulen_uu285 1284 0.00350877192982456
2_uuulen_uuuu497 0
4_uuulen_uuu171 0 171 0 0
5_uuulen_uuu75 0 0
我试过几种方法,但都不管用。以下是我尝试过的代码:

@input = <FILENAME>;

#Close the file
close FILENAME;

my @fractions;
my $y = 0;
for (my $x = 1; $x <= $#input; ++$x) {
    $fractions[$y] = (split (/\s/, $input[$x]))[4];
    ++$y;
}
my @sorted = sort {$b <=> $a} @fractions;
my $e = 1;
my $z = 0;
my $f = 0;
my @final;

do {
    do {
        if ((split (/\s/, $input[$e]))[4] == $sorted[$z]){
            $final[$f] = $input[$e];
            ++$e;
            ++$f;
        } else {
            ++$e;
        }
    } until ($e > $#input);

    do {
        ++$z;
    } until ($sorted[$z] != $sorted[$z - 1]);

    $e = 0;
} until ($z > $#sorted);

for (my $h = 0; $h <= $#final; ++$h) {
    print $final[$h] . "\n\n";
}
@input=;
#关闭文件
关闭文件名;
我的分数;
我的$y=0;
用于(我的$x=1;$x$#输入);
做{
++$z;
}直到($sorted[$z]!=$sorted[$z-1]);
$e=0;
}直到($z>$#排序);

对于(my$h=0;$h,在上一个代码示例中,您可以替换

my @sorted = sort { $b->[4] <=> $a->[4] } @input;
my@sorted=sort{$b->[4]$a->[4]}@input;

my@sorted=sort{(split(“”,$b))[4](split(“”,$a))[4]}@input;
甚至

my @sorted = sort { (split(/\s+/, $b))[4] <=> (split(/\s+/, $a))[4] } @input;
my@sorted=sort{(split(/\s+/,$b))[4](split(/\s+/,$a))[4]}@input;

如果输入数据没有带前导空格的行。

如果这有助于人们将来顺道而来-这里有一些不雅观的尝试,
sort()
lines.txt
(问题中的数据)的内容按第五列排序,并使用Perl one liner。这应该可以起作用:

perl -E 'say "@$_" for sort {$a->[4] <=> $b->[4]} map {[(split)]} <>' file
如果拆分模式不是空白,则可以将其替换为此处显示的默认模式(
\s+
):

perl -E 'say sort {(split(/\s+/,$a))[4] <=> (split(/\s+/,$b))[4]} <>' file
转换排序

我们可以一次完成
map
split
sort
吗?这是对第五列进行排序的一种简单方法:

perl -E 'say for sort map{ (split)[4] } <>' file
perl -E 'say for sort map{ [(split)[4], $_]->[0] } <>' file
这就像我们上面的第一个示例。如果不运行使用
for
创建的列表,而是
map
第二个元素并将其传递给
print
,我们会得到:

perl -E 'say map $_->[1], sort{$a->[0] <=> $b->[0]} map{[(split)[4],$_]} <>' file
perl-E'say map$>[1],sort{$a->[0]$b->[0]}map{[(split)[4],$]}文件
我们重新发明了,这是一个非常好的Perl习惯用法,它是;-)


  • 要了解其工作原理,您可以使用以下工具“可视化”事物:

    perl-MDDP-e'@t=sort-map{[(split/\s+/)[4],$\u]};p@t'文件

  • 从的帖子和一章中了解更多关于Perl习惯用法的信息


您可能还喜欢
List::UtilsBy
中的
sort\u by
功能:

use List::UtilsBy 'rev_nsort_by';

my @sorted = rev_nsort_by { (split(' ', $_))[4] } @input;

请注意,这里的基本内容是在
'
上拆分(这是在
/\s+/
上拆分的特殊缩写,但也忽略前导空格),而不是在
/\s/
上拆分(在单个空格上拆分,导致“第五列”)实际上不包含所需的数据,因为大多数列由多个空格分隔)@ysth是的,我知道,但在上面的示例中看不到有问题的行,从这个意义上讲,这很有效,非常感谢!我以前尝试过将split函数插入sort语句,但可能是使用/\s/而不是“”弄糟了,或者我犯了其他错误。再次感谢@Lisa正如一些人已经提到的,
\s
只在一个空格字符上分割数据,而在您的例子中,在列之间有许多空格字符,因此将所有空格字符都考虑在内的
\s+
更合适。@mpapec@ysth请参见上面的oneliner变体:-)。。。似乎总是可以使用较短版本的
map
和/或autosplit(使用
@F
)但是…“可移植”的紧急情况在不使用Unix排序时:-)
perl-E'say sort{(split(/\s+/,$b))[4](split(/\s+,$a))[4]}
perl -E 'say for sort map{ [(split)[4], $_]->[0] } <>' file
perl -E 'say $_->[1] for sort{$a->[0] <=> $b->[0]} map{[(split)[4], $_]} <>' file
perl -E 'say map $_->[1], sort{$a->[0] <=> $b->[0]} map{[(split)[4],$_]} <>' file
use List::UtilsBy 'rev_nsort_by';

my @sorted = rev_nsort_by { (split(' ', $_))[4] } @input;