简体   繁体   English

如果未定义数组中的所有元素,如何在Perl中对数组进行排序?

[英]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. 如果要修剪未定义的值,请使用grepukautz在其答案中建议的那样。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM