在Perl中,如何在数组中找到最后定义的元素?

时间:2013-07-27 15:57:14

标签: arrays perl for-loop conditional-statements defined

使用Perl,我希望在数组中找到最后一个定义元素。

到目前为止,我有以下内容:

#generating array
$array[100] = (undef);
$array[$columns[1]-1] = $columns [2];

#finding the last element that is defined
for ($i=100; $i>=0; $i--) {
    if (($array[$i] != undef) && (!defined($lastdef)) ){
        $lastdef=$i;
    }
}

我不确定为什么这不起作用。有任何改进建议,使用Perl?

4 个答案:

答案 0 :(得分:10)

  

我不确定为什么这不起作用。有任何改进建议,使用Perl?

你不知道它为什么不起作用的原因是因为你没有使用

use warnings;

如果有的话,你会被告知:

Use of uninitialized value in numeric ne (!=) at ...

因为!=numeric inequality operator,它会将其参数转换为数字。如果您未启用warnings,则会将undef静默转换为0。毋庸置疑,开启warnings是件好事,所以你不要犯这样的错误。

这是这一行:

if (($array[$i] != undef) ...

那应该是

if ((defined($array[$i]) ...

因为defined函数检查定义的值。这是一个奇怪的错误,因为你甚至在同一行上使用相同的功能。

此外,您可以通过执行

来简化此操作
if (defined($array[$i])) {
     $lastdef = $i;
     last;
}

last将在找到第一个未定义的值时结束循环。

您还应该知道可以在循环条件中使用非硬编码的最大值:

for (my $i = $#array; $i >= 0; $i--) {

$#array包含数组中现有最高索引的编号。

答案 1 :(得分:3)

使用List::Util函数可以更简洁。这将找到数组中定义的最后一个元素,但不是它的索引。要找到它的索引,您可以使用defined代替eq执行类似于 this 的回答。

use List::Util qw(first);

my $lastdef = first { defined($_) } reverse @array;

答案 2 :(得分:2)

以下是有点丑陋和模糊(与@TLP's excellent answer相比),但写作很有趣:

#!/usr/bin/env perl

use strict;
use warnings;

use feature 'say';

for my $i (0, 1) {
    my $array = generate_array(8, $i);
    say join ' ', map $_ // '_', @$array;
    say index_of_last_defined_element($array);
}

sub index_of_last_defined_element {
    my $x = $#{ $_[0] };
    my $v = $_[0]->[$x];
    return $x if defined($v) or $x < $[;
    $#{ $_[0] } -= 1;
    goto &index_of_last_defined_element;
}

sub generate_array {
    my $size = shift;
    my $array = [ (undef) x $size ];
    shift or return $array;
    $array->[rand $#$array] = 'x';
    return $array;
}

输出:

_ _ _ _ _ _ _ _
-1
_ _ _ _ _ x _ _
5

当然,这有点傻。您应该使用List::MoreUtils::last_index

use feature 'say';
use List::MoreUtils qw(last_index);

for my $i (0, 1) {
    my $array = generate_array(8, $i);
    say join ' ', map $_ // '_', @$array;
    say last_index { defined($_) } @$array;
}

答案 3 :(得分:1)

你需要从99开始,因为100个元素数组有索引:0 .. 99.并在找到元素后立即中断循环:

#!/usr/bin/perl

use strict;
use warnings;

my @array = (1, 2, undef);

my $lastdef;
for (my $i = $#array; $i>=0; $i--) {
    if (defined($array[$i])){
        $lastdef=$i;
        last;
    }
}

print $lastdef;

打印:1