[英]How do I sort an array in Perl if not all of the elements in the array are defined?
How do I sort an array if not all of the elements in the array are defined? 如果未定义数组中的所有元素,如何排序数组?
my @names;
$names[0] = "andrei";
$names[1] = "serghei";
$names[7] = "valerii";
$names[10] = "alexandr";
@names = sort @names; # aint working.
I apologize guys, I just don't get how to post questions here properly. 抱歉,我只是不知道如何在此处正确发布问题。 I tried the FAQ, I just don't get it.
我尝试了常见问题解答,但我没有。
undef
will is lower than any non-empty string, this is why it get's sorted at the beginning. undef
将低于任何非空字符串,这就是为什么它会在开始时进行排序的原因。 What you probably want is a "cleaned" result array with all undef
elements removed? 您可能想要的是一个“清除”结果数组,其中删除了所有
undef
元素? If so, here: 如果是这样,请在这里:
#!/usr/bin/perl
use strict;
use Data::Dumper;
my @names;
$names[1] = 'alpha';
$names[3] = 'gamma';
$names[10] = 'beta';
@names = sort grep { defined } @names;
print Dumper(\@names);
# $VAR1 = [
# 'alpha',
# 'beta',
# 'gamma'
# ];
To get rid of the undefined elements and sort the rest: 要摆脱未定义的元素并对其余元素进行排序:
sort grep defined, @names
To place the undefined elements at the start: 要将未定义的元素放在开始处:
sort { !defined($a) && !defined($b) ? 0
: !defined($a) ? -1
: !defined($b) ? +1
: $a cmp $b
} @names
To place the undefined elements at the end: 要将未定义的元素放在最后:
sort { !defined($a) && !defined($b) ? 0
: !defined($a) ? +1
: !defined($b) ? -1
: $a cmp $b
} @names
An easy one-liner to print your array including gaps: 一种简单的单线打印包括间隙的阵列:
print join "\n", @names;
Or if you want to put 'undefined' values in: 或者,如果您想将“未定义”值放入:
print join "\n", map {$_ || "undef"} @names;
If you want to trim out the undefined values, use grep
as ukautz suggested in his answer. 如果要修剪未定义的值,请使用
grep
如ukautz在其答案中建议的那样。
print join "\n", grep {defined} @names;
You can use the same approach to get the valid indices: 您可以使用相同的方法来获取有效的索引:
@idx = grep {defined $names[$_]} keys @names;
The above can be used if you wanted to sort the defined values and then insert them back in the defined positions. 如果要对定义的值进行排序,然后将其重新插入定义的位置,则可以使用上面的代码。 Sort of like an in-place sort.
有点像就地排序。
@sorted = grep {defined} sort @names;
map {$names[$idx[$_]] = $sorted[$_]} keys @sorted;
use strict;
use warnings;
use autodie;
use feature qw(say);
my @names;
$names[0] = "andrei";
$names[1] = "serghei";
$names[7] = "valerii";
$names[10] = "alexandr";
@names = sort grep { defined } @names;
for my $name ( @names ) {
say $name;
}
The grep { defined }
takes @names
and removes all the undefined values from @names
. grep { defined }
@names
并从@names
删除所有未定义的值。
If you don't want to remove the undefined stuff, you can do this: 如果您不想删除未定义的内容,则可以执行以下操作:
#! /usr/bin/env perl
#
use strict;
use warnings;
use autodie;
use feature qw(say);
my @names;
$names[0] = "andrei";
$names[1] = "serghei";
$names[7] = "valerii";
$names[10] = "alexandr";
no warnings qw(uninitialized);
@names = sort @names;
use warnings qw(uninitialized);
for my $name ( @names ) {
say $name if defined $name;;
}
The no warnings qw(initialized);
no warnings qw(initialized);
will turn off uninitialized warnings. 将关闭未初始化的警告。 I know that I'll run into trouble with unitialized warnging with
sort
, so I simply turn off the uninitialized warnings, and turn them right back on right after the sort
. 我知道在进行
sort
统一警告时会遇到麻烦,因此我只需要关闭未初始化的警告,然后在sort
后立即将其重新打开即可。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.