开发者

Perl: Good way to test if a value is in an array?

开发者 https://www.devze.com 2023-02-01 18:27 出处:网络
If I have an array: @int_array = (7,101,80,22,42); How can I check if the integer value 80 is in the array with开发者_高级运维out looping through every element?You can\'t without looping.That\'s p

If I have an array:

@int_array = (7,101,80,22,42);

How can I check if the integer value 80 is in the array with开发者_高级运维out looping through every element?


You can't without looping. That's part of what it means to be an array. You can use an implicit loop using grep or smartmatch, but there's still a loop. If you want to avoid the loop, use a hash instead (or in addition).

# grep
if ( grep $_ == 80, @int_array ) ...

# smartmatch
use 5.010001;
if ( 80 ~~ @int_array ) ...

Before using smartmatch, note:

http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#The_smartmatch_family_of_features_are_now_experimental:

The smartmatch family of features are now experimental

Smart match, added in v5.10.0 and significantly revised in v5.10.1, has been a regular point of complaint. Although there are a number of ways in which it is useful, it has also proven problematic and confusing for both users and implementors of Perl. There have been a number of proposals on how to best address the problem. It is clear that smartmatch is almost certainly either going to change or go away in the future. Relying on its current behavior is not recommended.

Warnings will now be issued when the parser sees ~~, given, or when. To disable these warnings, you can add this line to the appropriate scope


CPAN solution: use List::MoreUtils

use List::MoreUtils qw{any}; 
print "found!\n" if any { $_ == 7 } (7,101,80,22,42);

If you need to do MANY MANY lookups in the same array, a more efficient way is to store the array in a hash once and look up in the hash:

@int_array{@int_array} = 1;
foreach my $lookup_value (@lookup_values) {
    print "found $lookup_value\n" if exists $int_array{$lookup_value}
}

Why use this solution over the alternatives?

  • Can't use smart match in Perl before 5.10. According to this SO post by brian d foy]2, smart match is short circuiting, so it's as good as "any" solution for 5.10.

  • grep solution loops through the entire list even if the first element of 1,000,000 long list matches. any will short-circuit and quit the moment the first match is found, thus it is more efficient. Original poster explicitly said "without looping through every element"

  • If you need to do LOTs of lookups, the one-time sunk cost of hash creation makes the hash lookup method a LOT more efficient than any other. See this SO post for details


Yet another way to check for a number in an array:

#!/usr/bin/env perl

use strict;
use warnings;

use List::Util 'first';

my @int_array       = qw( 7 101 80 22 42 );
my $number_to_check = 80;

if ( first { $_ == $number_to_check } @int_array ) {
    print "$number_to_check exists in ", join ', ', @int_array;
}

See List::Util.


if ( grep /^80$/, @int_array ) {
    ...
}


If you are using Perl 5.10 or later, you can use the smart match operator ~~:

my $found = (80 ~~ $in_array);
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号