[英]Perl sort with regular expression
我有一個像這樣的perl數組字符串:
my @arr = ( "gene1 (100)", "gene2 (50)", "gene3 (120)", ... );
如何用括號中的整數對數組進行排序?
使用變換來比較字符串中的第一個數字
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)
Perl中內置的sort
允許您傳遞代碼引用作為其第一個參數,以定義應如何進行排序。 在此代碼ref中,您可以使用任何您想要的功能。
由於您希望使用正則表達式,因此創建與括號中的數字匹配的sub
並在排序函數中使用它是有意義的。
您需要為$a
和$b
調用一次,這兩個變量將針對每輪排序對進行相互比較。 您應該使用<=>
運算符 ,該運算符用於按升序對數字進行排序。
這是一個非常詳細的版本。
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)")
這顯示了直截了當的方式。 該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)
List::UtilsBy
CPAN模塊提供了一個函數nsort_by
,它通過按數字順序排序來排序值列表,每個值的代碼塊返回的值。
在您的情況下,它可用於提取該數字:
use List::UtilsBy 'nsort_by';
@sorted = nsort_by { m/\((\d+)/ and $1 } @strings
這比使用代碼直接提取和比較$a
和$b
的兩個數字的常規sort
調用更有效,因為它只需要從每個值中提取一次數,而不是每次成對比較一次。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.