如何在perl中对包含两个数字的字符串数组进行排序?

per*_*ver 0 arrays sorting string perl numbers

我有以下字符串数组:

Expt5_Expt12
Expt5_Expt1
Expt12_Expt2
Expt11_Expt8
Expt1_Expt2
Expt10_Expt1
Expt10_Expt4
Expt11_Expt1
Run Code Online (Sandbox Code Playgroud)

我想按第一个数字排序这些字符串,然后用第二个数字排序第二个数字,这样我就有了这样的列表:

Expt1_Expt2
Expt5_Expt1
Expt5_Expt12
Expt10_Expt1
Expt10_Expt4
Expt11_Expt1
Expt11_Expt8
Expt12_Expt2
Run Code Online (Sandbox Code Playgroud)

我只找到了解决方案,只按第一个数字或第二个数字排序.我尝试了一些使用正则表达式和排序函数的东西,但我没有找到解决方案.

Sob*_*que 9

按功能排序非常简单.该函数具有返回-1,0或1取决于如果$a$b是之前或之后.(如评论中所述 - 它可以是任何正值或负值 - 关键点是元素是在彼此之前还是之后).

$a并且$b是专门用于perl和排序的"特殊"变量.因此,它们不需要声明,并且在代码中使用其他内容是一个非常糟糕的主意.但那么,谁还使用单字母变量呢?

所以你的价值观:

#!/usr/bin/env perl
use strict;
use warnings;

sub custom_sort {
   my ( $a1, $a2 ) = ( $a =~ m/(\d+)/g );   #extract the numeric elements
   my ( $b1, $b2 ) = ( $b =~ m/(\d+)/g );

   return ( $a1 <=> $b1     #return the result of this comparison
         || $a2 <=> $b2 );  #unless it's zero, then we return the result of this.
}


my @list = <DATA>;    
print sort custom_sort @list; 

__DATA__
Expt5_Expt12
Expt5_Expt1
Expt12_Expt2
Expt11_Expt8
Expt1_Expt2
Expt10_Expt1
Expt10_Expt4
Expt11_Expt1
Run Code Online (Sandbox Code Playgroud)

你可以使这更简洁,但实质是:

  • 提取第一个和第二个值.
  • 然后使用||运算符 - 如果$a1 <=> $b1为零,则计算表达式的第二部分.
  • <=>是一个'小于,等于,大于'运算符,它根据数字比较返回-1,0或1.对于字符串,您可以使用cmp它来做同样的事情.

(你可以打印这些,如果你想调试这种方法对于每次比较是如何"工作"的,如果你做了一些复杂的事情,这真的很方便)