在Perl中,我如何找到数组中给定值的索引?

16
$VAR1 = [
          '830974',
          '722065',
          '722046',
          '716963'
        ];

如何计算值为"722065"的数组索引?


只需使用for循环查找即可。如果数组中有两个相等的值怎么办? - Mark Canlas
1
你有尝试过任何东西吗?这是作业吗? - jsoverson
1
@jsoverson:我是perl的新手。自学项目。 - Antonio Lopes
2
自Perl 5.10以来,您还可以使用my($index) = grep {$array[$_] ~~ $element} 0..$#array;。请参见此处:https://dev59.com/pnA75IYBdhLWcg3wkZ-A#3222653 - mivk
7个回答

33
List::MoreUtils中的firstidx函数可以帮助解决问题:
use strict;
use warnings;
use List::MoreUtils qw(firstidx);

my @nums = ( '830974', '722065', '722046', '716963' );
printf "item with index %i in list is 722065\n", firstidx { $_ eq '722065' } @nums;

__END__

列表中索引为1的项是722065。

如果您想定位多个这样的索引,可以使用List::MoreUtils::indexes。 - Nate Glenn

26

使用List::Util,它是一个核心模块,不同于List::MoreUtils,后者并非核心模块:

use List::Util qw(first);

my @nums = ( '830974', '722065', '722046', '716963' );
my $index = first { $nums[$_] eq '722065' } 0..$#nums;

15

以下是如何查找给定值出现的所有位置:

#!/usr/bin/perl

use strict;
use warnings;

my @x = ( 1, 2, 3, 3, 2, 1, 1, 2, 3, 3, 2, 1 );
my @i = grep { $x[$_] == 3 } 0 .. $#x;
print "@i\n";

如果你只需要第一个索引,你应该使用List::MoreUtils::first_index


1
老实说,不要提到 $[。它很模糊,我记得已经被弃用了,而且没有诚实的理由使用它。 - tsee
2
那是Perl的街头信誉材料,哈哈 :-) - Leonardo Herrera

7
如果您只需要查找一个项目,可以像其他人建议的那样使用firstidx
如果您需要进行多次查找,请建立索引。
如果您的数组项是唯一的,则构建索引非常简单。但是构建一个处理重复项的索引也不太困难。以下是两个示例:
use strict;
use warnings;

use Data::Dumper;

# Index an array with unique elements.
my @var_uniq  = qw( 830974 722065 722046 716963 );
my %index_uniq  = map { $var_uniq[$_] => $_ } 0..$#var_uniq;

# You could use hash slice assinment instead of map:
# my %index_uniq;
# @index_uniq{ @var_uniq } = 0..$#var_uniq

my $uniq_index_of_722065   = $index_uniq{722065};
print "Uniq 72665 at: $uniq_index_of_722065\n";
print Dumper \%index_uniq;

# Index an array with repeated elements.
my @var_dupes = qw( 830974 722065 830974 830974 722046 716963 722065 );
my %index_dupes;
for( 0..$#var_dupes ) {
    my $item = $var_dupes[$_];

    # have item in index?
    if( $index_dupes{$item} ) {
        # Add to array of indexes
        push @{$index_dupes{$item}}, $_;
    }
    else {
        # Add array ref with index to hash.
        $index_dupes{$item} = [$_];
    }
}

# Dereference array ref for assignment:
my @dupe_indexes_of_722065 = @{ $index_dupes{722065} };

print "Dupes 722065 at: @dupe_indexes_of_722065\n";
print Dumper \%index_dupes;

3
这是一个使用哈希表进行快速查找的简单尝试。
my $VAR1 = [ '830974', '722065', '722046', '716963' ];

my %reverse;
$reverse{$VAR1->[$_]} = $_ for 0 .. @$VAR1 - 1;

print $reverse{722065};

这并不考虑具有重复值的数组。我不建议在生产代码中使用此解决方案。


在存在重复值的情况下,您将只获得与第一个匹配项相同的元素。如果长期存在的数组被查询多次,这可能非常有用。 - Leonardo Herrera
2
我不确定我是否理解了上面的评论,但是根据代码编写方式,在出现重复数值的情况下,最高的索引值将获胜。 - Mark Canlas

1

4
重新阅读精细手册(RRTFM-ing)是一种非常有益的体验。第一次阅读文档时,很多内容都让我摸不着头脑。但每一次后续阅读都揭示了新的含义。重新(再次)阅读手册可以学到大量新知识! - daotoad
2
如果大多数人至少读一遍,我会感到满意。人们经常问FAQ的相关性如何,而StackOverflow是一个很好的自然实验:每个人都会重新提出FAQ问题。 - brian d foy
2
@daotoad:也许是因为我一直在更改常见问题解答,所以导致你看到的不同。 :) - brian d foy

0
use strict;
use Data::Dumper;

sub invert
{
 my $i=0;
 map { $i++ => $_ } @_;
}

my @a = ('a','b','c','d','e');

print Dumper @a;

print Dumper invert @a;

1
使用严格模式; 使用Data::Dumper模块; sub mirror { my $i=0; map { $i++ => $_ } @{ shift @_ }; } my @a = ('a','b','c','d','e'); my %b = mirror @a; print Dumper @a; print Dumper %b; $a[1] = 'whoa...'; print Dumper @a; print Dumper %b; $a[3] = 'IKNOWRIGHT!'; print Dumper @a; print Dumper %b; - Sean Morris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接