Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 如何在perl中对包含两个数字的字符串数组进行排序?_Arrays_String_Perl_Sorting_Numbers - Fatal编程技术网

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

Arrays 如何在perl中对包含两个数字的字符串数组进行排序?,arrays,string,perl,sorting,numbers,Arrays,String,Perl,Sorting,Numbers,我有以下字符串数组: Expt5_Expt12 Expt5_Expt1 Expt12_Expt2 Expt11_Expt8 Expt1_Expt2 Expt10_Expt1 Expt10_Expt4 Expt11_Expt1 我想按第一个数字对这些字符串进行排序,并按第二个数字对第二个优先级的字符串进行排序,这样我就有了这样一个列表: Expt1_Expt2 Expt5_Expt1 Expt5_Expt12 Expt10_Expt1 Expt10_Expt4 Expt11_Expt1 Expt

我有以下字符串数组:

Expt5_Expt12
Expt5_Expt1
Expt12_Expt2
Expt11_Expt8
Expt1_Expt2
Expt10_Expt1
Expt10_Expt4
Expt11_Expt1
我想按第一个数字对这些字符串进行排序,并按第二个数字对第二个优先级的字符串进行排序,这样我就有了这样一个列表:

Expt1_Expt2
Expt5_Expt1
Expt5_Expt12
Expt10_Expt1
Expt10_Expt4
Expt11_Expt1
Expt11_Expt8
Expt12_Expt2

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

按函数排序非常简单。函数必须返回-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
#/usr/bin/env perl
严格使用;
使用警告;
次自定义排序{
my($a1,$a2)=($a=~m/(\d+)/g)#提取数字元素
我的($b1,$b2)=($b=~m/(\d+)/g);
return($a1$b1#返回此比较的结果
||$a2$b2);#除非为零,否则我们将返回此结果。
}
我的@list=;
打印排序自定义\排序@列表;
__资料__
Expt5_Expt12
Expt5_Expt1
Expt12\u Expt2
Expt11\u Expt8
Expt1_Expt2
Expt10\u Expt1
出口10_出口4
Expt11\u Expt1
您可以使其更加简洁,但其实质是:

  • 提取第一个和第二个值
  • 然后使用
    |
    运算符-这样,如果
    $a1$b1
    为零,它将计算表达式的第二部分
  • 是一个“小于、等于、大于”运算符,根据数值比较返回-1、0或1。对于字符串,可以使用
    cmp
    执行相同的操作

(如果您希望调试此排序在每次比较中的“工作”方式,您可以打印这些,如果您正在做一些复杂的事情,这非常方便)

这与其他人发布的解决方案大致相同,但通过使用
map

use strict;
use warnings;

my @data = <DATA>;

print sort {
    my @ab = map [ /\d+/g ], $a, $b;
    $ab[0][0] <=> $ab[1][0] or $ab[0][1] <=> $ab[1][1];
} @data;

__DATA__
Expt5_Expt12
Expt5_Expt1
Expt12_Expt2
Expt11_Expt8
Expt1_Expt2
Expt10_Expt1
Expt10_Expt4
Expt11_Expt1
使用


谢谢你的快速回答。它工作得很好,我学到了一些新东西。小诡辩:
sort
不关心块返回的特定值。它关心它与0的关系。您应该向我们展示您尝试过的内容,以便我们可以帮助您修复它。
Expt1_Expt2
Expt5_Expt1
Expt5_Expt12
Expt10_Expt1
Expt10_Expt4
Expt11_Expt1
Expt11_Expt8
Expt12_Expt2
use Sort::Key::Multi qw(i2_keysort); #i2 means two integer keys

my @sorted = i2_keysort { /(\d+)\D+(\d+)/ } @data;