我刚刚开始学习 Perl,因此我的问题可能看起来很愚蠢。我提前道歉。
我有一个列表说@data
,其中包含从输入中读取的行列表。这些行包含由(未知数量的)空格分隔的数字。
现在,我想对它们进行排序并打印出来,但不是按字典顺序,而是根据出现在行上的第一个数字的数值。
我知道这一定很简单,但我不知道该怎么做?
提前致谢,
您可以使用Schwartzian 变换,使用正则表达式捕获行中的第一个数字
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+)/
此处使用正则表达式来捕获首先出现的任何非空白。比较行时,排序使用数组 ref 中捕获的数字。最后,最后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
但正如您所看到的,它已正确排序。我不会建议这个解决方案,但我认为在这种情况下这是一个很好的演示。
您可以使用排序功能:
@sorted_data = sort(@data);