簡體   English   中英

使用正則表達式進行Perl排序

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM