我和我有一系列裁判。像
这样的东西$a[0] = [qw( 1 2 3 4 )];
$a[1] = [qw( a b c d )];
1
,2
,3
,4
实际上是用于导航的网站面包屑(Home
,Profile
,{ {1}},Contact-us
)。
现在,我必须对这个阶梯进行排序(并且在perl 5.8中使用稳定排序不是一个可悲的选择)
排序标准是
例如,如果数组最初包含
Contact-me-specifically
然后在排序后,数组应该包含
$a[0] = [qw( 1 2 3 4 )];
$a[1] = [qw( 1 2 3 )];
但如果数组如下: -
$a[0] = [qw( 1 2 3 )];
$a[1] = [qw( 1 2 3 4 )];
然后排序后,
$a[0] = [qw( 1 2 3 )];
$a[1] = [qw( a b c )];
我无法以这种方式工作,我尝试过。
$a[0] = [qw( 1 2 3 )];
$a[1] = [qw( a b c )];
有人可以帮助我吗?
答案 0 :(得分:4)
您的数据结构(链接列表)的描述以及sort
例程(arrayrefs)中的实现并不完全适合;我将假设后者。
通过按位置排序作为次要标准,可以使非稳定排序稳定:
sort { normally or by_index } @stuff
通常,您似乎想要比较数组长度。为了能够测试索引,您必须以某种方式使当前元素的索引可用。您可以通过两种方式实现:
这看起来像是:
my @sorted_indices =
sort { @{ $array[$b] } <=> @{ $array[$a] } or $a <=> $b } 0 .. $#array;
my @sorted = @array[@sorted_indices]; # do a slice
您之前使用$a <=> $b
做的事情是比较引用。这并不能保证做任何有意义的事情。
测试sort
:
use Test::More;
my @array = (
[qw/1 2 3/],
[qw/a b c/],
[qw/foo bar baz qux/],
);
my @expected = (
[qw/foo bar baz qux/],
[qw/1 2 3/],
[qw/a b c/],
);
...; # above code
is_deeply \@sorted, \@expected;
done_testing;
答案 1 :(得分:2)
您的代码不起作用,因为您希望$a
和$b
在一个地方(@$b <=> @$a
)包含元素的值,而在另一个地方包含元素的索引($a <=> $b
)。
您需要比较中的索引,因此您的比较函数将需要索引。
通过将数组的索引传递给sort
,您可以访问索引和这些索引处的值,因此您的代码将包括
sort { ... } 0..$#array;
在我们完成排序之后,我们想要检索这些索引的元素。为此,我们可以使用
my @sorted = map $array[$_], @sorted_indexes;
或
my @sorted = @array[ @sorted_indexes ];
总之,我们得到:
my @sorted =
map $array[$_],
sort { @{ $array[$a] } <=> @{ $array[$b] } || $a <=> $b }
0..$#array;
或
my @sorted = @array[
sort { @{ $array[$a] } <=> @{ $array[$b] } || $a <=> $b }
0..$#array
];
答案 2 :(得分:1)
我认为我们需要清理你的排序算法。你说:
以下是一个例子:
$array[0] = [ qw(1 a b c d e) ];
$array[2] = [ qw(1 2 b c d e) ];
$array[3] = [ qw(a b c) ];
$array[4] = [ qw(a b c d e) ];
你希望他们按照这种方式排序:
$array[3] = [ qw(a b c) ];
$array[2] = [ qw(1 2 b c d e) ];
$array[0] = [ qw(1 a b c d e) ];
$array[4] = [ qw(a b c d e) ];
这是对的吗?
这个怎么样?
$array[0] = [ qw(100, 21, 15, 32) ];
$array[1] = [ qw(32, 14, 32, 20) ];
按数字排序,$array[1]
应在$array[0]
之前,但按字符串$array[0]
排序在$array[1]
之前。
另外,你注意到我无法判断$array[0]
是否应该在$array[1]
之前或之后,直到我查看数组的第二个元素。
这使得在单行功能上很难进行排序。即使你可以以某种方式减少它,它也会让某人很难分析你在做什么,或者让你调试声明。
幸运的是,您可以使用整个子例程作为排序例程:
use warnings;
use strict;
use autodie;
use feature qw(say);
use Data::Dumper;
my @array;
$array[0] = [ qw(1 2 3 4 5 6) ];
$array[1] = [ qw(1 2 3) ];
$array[2] = [ qw(a b c d e f) ];
$array[3] = [ qw(0 1 2) ];
my @sorted_array = sort sort_array @array;
say Dumper \@sorted_array;
sub sort_array {
#my $a = shift; #Array reference to an element in @array
#my $b = shift; $Array reference to an element in @array
my @a_array = @{ $a };
my @b_array = @{ $b };
#
#First sort on length of arrays
#
if ( scalar @a_array ne scalar @b_array ) {
return scalar @a_array <=> scalar @b_array;
}
#
# Arrays are the same length. Sort on first element in array that differs
#
for my $index (0..$#a_array ) {
if ( $a_array[$index] ne $b_array[$index] ) {
return $a_array[$index] cmp $b_array[$index];
}
}
#
# Both arrays are equal in size and content
#
return 0;
}
返回:
$VAR1 = [
[
'0',
'1',
'2'
],
[
'1',
'2',
'3'
],
[
'1',
'2',
'3',
'4',
'5',
'6'
],
[
'a',
'b',
'c',
'd',
'e',
'f'
]
];