我试图按照其元素部分的大小对数组进行排序.这些项目遵循一种模式x/y[.../z],我希望它们按照项目的数量排序.例如1/2,分裂后有两个项目/,12/365/85有三个.在这样一个看似简单的片段中,我似乎无法弄清楚我做错了什么.
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my @dummy_arr = ['12345/3/365/45/12', '1/2', '3/2', '1/2/3', '2/3/4'];
@dummy_arr = sort { scalar ( split /\//, $a ) < scalar ( split /\//, $b ) } @dummy_arr;
print Dumper(\@dummy_arr);
Run Code Online (Sandbox Code Playgroud)
输出:
$VAR1 = [
[
'12345/3/365/45/12',
'1/2',
'3/2',
'1/2/3',
'2/3/4'
]
];
Run Code Online (Sandbox Code Playgroud)
预期产量:
$VAR1 = [
'1/2',
'3/2',
'1/2/3',
'2/3/4',
'12345/3/365/45/12'
];
Run Code Online (Sandbox Code Playgroud)
sim*_*que 11
你混淆了几件事.
你把一个数组引用放入你的@dummy_arr.
Run Code Online (Sandbox Code Playgroud)my @dummy_arr = [ '12345/3/365/45/12', '1/2', '3/2', '1/2/3', '2/3/4' ];
这相当于:
my @dummy_arr = ( [ '12345/3/365/45/12', '1/2', '3/2', '1/2/3', '2/3/4' ] );
Run Code Online (Sandbox Code Playgroud)
在您的Dumper输出中也是可见的.
$VAR1 = [ # <-- because of the ref \@dummy_arr you pass to Dumper
[ # <-- first elem is already an array ref
'12345/3/365/45/12',
'1/2',
'3/2',
'1/2/3',
'2/3/4'
]
];
Run Code Online (Sandbox Code Playgroud)
所以当你这样做时sort { ... } @dummy_arr,只传递了一个值sort.因为sort它是聪明的,所以它会跳过,因为没有什么可以排序,如果只有$a,但没有$b.当你把一个{ warn $a; scalar ... }放入sortlambda 时,这就变得很明显了.没有警告,因此它永远不会被调用.
但是你还是没有排序.该sort拉姆达需要返回类似的东西 -1,0或1.
如果指定了SUBNAME,则它会给出一个子例程的名称,该子例程返回一个小于,等于或大于0的整数,具体取决于列表元素的排序方式.
但你正在使用<,只返回1或0.您需要使用<=>数字比较.
my @dummy_arr = ( '12345/3/365/45/12', '1/2', '3/2', '1/2/3', '2/3/4' );
@dummy_arr = sort { scalar( split /\//, $a ) <=> scalar( split /\//, $b ) }
@dummy_arr;
print Dumper( \@dummy_arr );
__END__
$VAR1 = [
'1/2',
'3/2',
'1/2/3',
'2/3/4',
'12345/3/365/45/12'
];
Run Code Online (Sandbox Code Playgroud)
最后,因为分裂是一个昂贵的操作需要重复很多,如果有很多数组中的元素,你可能想使用一个使用Schwartzian变换了这一点.
my @dummy_arr = ( '12345/3/365/45/12', '1/2', '3/2', '1/2/3', '2/3/4' );
@dummy_arr =
map { $_->[0] }
sort { $a->[1] <=> $b->[1] }
map { [ $_, scalar split( qr{/}, $_ ) ] } @dummy_arr;
Run Code Online (Sandbox Code Playgroud)
这会产生相同的输出,但会为CPU交换内存,因此速度更快.