我有一个像这样的perl数组字符串:
my @arr = ( "gene1 (100)", "gene2 (50)", "gene3 (120)", ... );
如何用括号中的整数对数组进行排序?
答案 0 :(得分:5)
使用transform比较字符串
中的第一个数字use strict;
use warnings;
my @arr = ( "gene1 (100)", "gene2 (50)", "gene3 (120)");
my @sorted = map {$_->[0]}
sort {$a->[1] <=> $b->[1]}
map {[$_, /\b(\d+)\b/]} @arr;
print "$_\n" for @sorted;
输出:
gene2 (50)
gene1 (100)
gene3 (120)
答案 1 :(得分:3)
Perl中的sort
built-in允许您传递代码引用作为其第一个参数,以定义应如何进行排序。在此代码ref中,您可以使用任何您想要的功能。
由于您希望使用正则表达式,因此创建与括号中的数字匹配的sub
并在排序函数中使用它是有意义的。
您需要为$a
和$b
调用一次,这两个变量将针对每轮排序对进行相互比较。您应该使用<=>
operator,它用于按升序排序数字。
这是一个非常详细的版本。
use strict;
use warnings;
use Data::Dump;
my @arr = ( "gene1 (100)", "gene2 (50)", "gene3 (120)", );
dd sort { get_number($a) <=> get_number($b) } @arr;
sub get_number {
my ( $string ) = @_;
return $1 if $string =~ m/\((\d+)\)/;
return 0; # assume it goes last if there is no number
}
输出:
("gene2 (50)", "gene1 (100)", "gene3 (120)")
答案 2 :(得分:2)
这显示了直截了当的方式。 sort
块将$aa
和$bb
分别设置为$a
和$b
中的数字值。然后使用<=>
以数字方式对它们进行比较。
除非基本技术证明太慢,否则不需要更加模糊的转换方法。
use strict;
use warnings;
use 5.010;
my @arr = ( "gene1 (100)", "gene2 (50)", "gene3 (120)", );
my @sorted = sort {
my ($aa) = $a =~ / \( (\d+) \) /x;
my ($bb) = $b =~ / \( (\d+) \) /x;
$aa <=> $bb;
} @arr;
say for @sorted;
<强>输出强>
gene2 (50)
gene1 (100)
gene3 (120)
答案 3 :(得分:1)
List::UtilsBy
CPAN模块提供了一个函数nsort_by
,它通过按数字顺序排序来排序值列表,每个值上的代码块返回的值。
在您的情况下,它可用于提取该数字:
use List::UtilsBy 'nsort_by';
@sorted = nsort_by { m/\((\d+)/ and $1 } @strings
这比使用代码的常规sort
调用更有效,可以直接从$a
和$b
提取和比较两个数字,因为它只需从每个数字中提取数字价值一次,而不是每次成对比较一次。