2012-04-20 3 views
3

Учитывая array @A, мы хотим проверить, есть ли в нем element $B. Один из способов сказать это:Perl: Поиск элемента в массиве

Foreach $element (@A){ 
    if($element eq $B){ 
     print "$B is in array A"; 
    } 
} 

Однако, когда дело доходит до Perl, я всегда думаю о самом элегантном пути. И это то, что я имею в виду: Есть ли способ узнать, если массив А содержит B, если преобразовать к переменной строки и использовать

index(@A,$B)=>0 

Возможно ли это?

+4

'Grep {$ _ эк $ B} @ Ā'? – cHao

+0

Связанные: http://stackoverflow.com/questions/7898499/grep-to-find-item-in-perl-array http://stackoverflow.com/questions/3086874/find-the-item-in-an- array-that-meets-a-specific-criteria-if-there-is-one-perl – daxim

ответ

13

Есть много способов, чтобы выяснить, присутствует ли в массиве или нет элемент:

  1. Использование Еогеасп

    foreach my $element (@a) { 
        if($element eq $b) { 
         # do something    
         last; 
        } 
    } 
    
  2. Использование Grep:

    my $found = grep { $_ eq $b } @a; 
    
  3. Использование List::Util модуля

    use List::Util qw(first); 
    
    my $found = first { $_ eq $b } @a; 
    
  4. Использование Hash инициализируется кусочком

    my %check; 
    @check{@a} =(); 
    
    my $found = exists $check{$b}; 
    
  5. Использование Hash инициализируется карте

    my %check = map { $_ => 1 } @a; 
    
    my $found = $check{$b}; 
    
+0

List :: Util :: first() пример (потенциально) тонко неверен при поиске ложных значений, так как '$ found' также будет оценивать значение false. ('die if $ found' ... oops!) [List :: MoreUtils :: any] (http://search.cpan.org/perldoc?List::MoreUtils) делает правильные вещи здесь. – pilcrow

6
use 5.10.1; 

$B ~~ @A and say '$B in @A'; 
+0

Вы должны быть очень осторожны с этим, потому что это распределяет соответствие по элементам. Если @A имеет ссылочный элемент массива, который содержит $ B, это будет по-прежнему соответствовать, хотя $ B не является элементом верхнего уровня @A. Умный матч принципиально нарушен для этого и многих других причин. –

0
use List::AllUtils qw/ any /; 
print "\@A contains $B" if any { $B eq $_ } @A; 
+2

Я бы порекомендовал 'first' в этом случае, так как ему не нужно проходить весь массив. Он может остановиться, когда элемент найден. – bvr

+0

любой может остановиться и потому, что для проверки требуется только один элемент. –

+0

Остерегайтесь того, что 'first' также может вернуть ложное значение, если оно найдет, например,« 0 », что может помешать примеру, приведенному в этом ответе. 'any' имеет желаемую семантику. – pilcrow

Смежные вопросы