Reputation: 512
$VAR1 = [
'830974',
'722065',
'722046',
'716963'
];
How can I calculate the array index for the value "722065"?
Upvotes: 16
Views: 43600
Reputation: 62236
The firstidx
function from List::MoreUtils can help:
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;
Outputs:
item with index 1 in list is 722065
Upvotes: 33
Reputation: 118166
Here is how you would find all the positions at which a given value appears:
#!/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";
If you only need the first index, you should use List::MoreUtils::first_index.
Upvotes: 15
Reputation: 1
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;
Upvotes: -1
Reputation: 122519
using List::Util
, which is a core module, unlike List::MoreUtils
, which is not:
use List::Util qw(first);
my @nums = ( '830974', '722065', '722046', '716963' );
my $index = first { $nums[$_] eq '722065' } 0..$#nums;
Upvotes: 26
Reputation: 27234
If you only need to look up the one item, use firstidx
as others have said.
If you need to do many lookups, build an index.
If your array items are unique, building an index is quite simple. But it's not much more difficult to build one that handles duplicate items. Examples of both follow:
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;
Upvotes: 6
Reputation: 9583
Here's hastily written attempt at a reverse look-up using a hash.
my $VAR1 = [ '830974', '722065', '722046', '716963' ];
my %reverse;
$reverse{$VAR1->[$_]} = $_ for 0 .. @$VAR1 - 1;
print $reverse{722065};
This does not account for arrays with duplicate values. I do not endorse this solution for production code.
Upvotes: 2