perl排序数组:保留一个以#就地开头的项目

eal*_*eon 4 sorting perl

有没有办法修改任何字符串以#开头的排序被忽略即保持其索引?

例如:

my @stooges = qw(
        Larry
        Curly
        Moe
        Iggy
    );

my @sorted_stooges = sort @stooges;
Run Code Online (Sandbox Code Playgroud)

@sorted_stooges 应该给:

Curly
Iggy
Larry
Moe
Run Code Online (Sandbox Code Playgroud)

现在,如果我将#添加到Curly

my @stooges = qw(
            Larry
            #Curly
            Moe
            Iggy
        );

my @sorted_stooges = sort @stooges;
Run Code Online (Sandbox Code Playgroud)

我想@sorted_stooges是:

Iggy
#Curly
Larry
Moe
Run Code Online (Sandbox Code Playgroud)

ike*_*ami 10

就地解决方案:

my @indexes_to_sort = grep { $array[$_] !~ /^#/ } 0..$#array;
my @sorted_indexes = sort { $array[$a] cmp $array[$b] } @indexes_to_sort;
@array[@indexes_to_sort] = @array[@sorted_indexes];
Run Code Online (Sandbox Code Playgroud)

要么

my @indexes_to_sort = grep { $array[$_] !~ /^#/ } 0..$#array;
@array[@indexes_to_sort] = sort @array[@indexes_to_sort];
Run Code Online (Sandbox Code Playgroud)

要么

my $slice = sub { \@_ }->( grep { !/^#/ } @array );
@$slice[0..$#$slice] = sort @$slice;
Run Code Online (Sandbox Code Playgroud)

(不幸的是,@$slice = sort @$slice;它不起作用 - 它取代了它们的元素@$slice而不是分配它们 - 但找到了合适的替代方案.)


amo*_*mon 5

提取要排序的元素,然后使用已排序的元素更新原始数组:

my @stooges = qw( Larry #Curly Moe Iggy );
my @sorted_items = sort grep { not /^#/ } @stooges;
my @sorted_stooges = map { /^#/ ? $_ : shift @sorted_items } @stooges;
say for @sorted_stooges;
Run Code Online (Sandbox Code Playgroud)

在他们的回答中,@ higami建议使用这种方法的一种变体,即提取要排序的元素的索引,而不是元素本身.该解决方案允许使用列表切片优雅地交换数组元素.