根据每条线上第一个元素的数值对线进行排序?

时间:2013-10-11 09:54:14

标签: perl sorting

我刚刚开始学习Perl,因此我的问题可能看起来很愚蠢。我提前道歉。

我有一个列表@data,其中包含从输入中读取的行列表。这些行包含由(未知数量)空格分隔的数字。

现在,我想对它们进行排序并打印出来,但不是按字典顺序排列,而是根据行上出现的第一个数字的数值。

我知道这一定是非常简单但我无法弄明白该怎么做?

提前致谢,

2 个答案:

答案 0 :(得分:6)

您可以使用Schwartzian transform,使用正则表达式捕获行中的第一个数字

use strict;
use warnings;

my @sorted =    map $_->[0],
                sort { $a->[1] <=> $b->[1] }
                map { [ $_, /^(-?[\d.]+)/ ] } <DATA>;
print @sorted;

__DATA__
21  13  14
0   1   2
32  0   4
11  2   3
1   3   3

<强>输出:

0       1       2
1       3       3
11      2       3
21      13      14
32      0       4

从后面读取变换,<DATA>是我们使用的文件句柄,它将返回文件中的行列表。第一个map语句返回一个数组引用[ ... ],它包含原始行,以及该行中捕获的第一个数字。或者,您可以在此处使用正则表达式/^(\S+)/来捕获最先出现的任何非空格。排序在比较行时使用数组引用中捕获的数字。最后,最后一个map将数组ref转换回原始值,存储在$_->[0]中。

请注意,这取决于行开头有数字的行。如果可能遗漏或空白,这将产生一些不可预见的后果。


请注意,只使用简单的数字排序也会“正常”,因为Perl会将您的一行转换为正确的数字,假设每行以数字后跟空格开头。您会收到一些警告,例如Argument "21 13 14\n" isn't numeric in sort。例如,如果我用

替换上面的代码
my @foo = sort { $a <=> $b } <DATA>;

我会得到输出:

Argument "21    13      14\n" isn't numeric in sort at foo.pl line 6, <DATA> line 5.
Argument "0     1       2\n" isn't numeric in sort at foo.pl line 6, <DATA> line 5.
Argument "32    0       4\n" isn't numeric in sort at foo.pl line 6, <DATA> line 5.
Argument "11    2       3\n" isn't numeric in sort at foo.pl line 6, <DATA> line 5.
Argument "1     3       3\n" isn't numeric in sort at foo.pl line 6, <DATA> line 5.
0       1       2
1       3       3
11      2       3
21      13      14
32      0       4

但正如您所看到的,它已正确排序。我不会建议这个解决方案,但我认为这是一个很好的演示。

答案 1 :(得分:-1)

您可以使用排序功能:

@sorted_data = sort(@data);