Как я могу проверить, есть ли значение в списке в Perl? - PullRequest
1 голос
/ 21 апреля 2010

У меня есть файл, в котором каждая строка представляет собой целое число, которое представляет идентификатор. Что я хочу сделать, это просто проверить, есть ли некоторые конкретные идентификаторы в этом списке. Но код не работал. Он никогда не говорит мне, что существует, даже если 123 является строкой в ​​этом файле. Не знаю почему? Помощь оценена.

open (FILE, "list.txt") or die ("unable to open !");

    my @data=<FILE>;

    my %lookup  =map {chop($_) => undef} @data;

    my $element= '123';
    if (exists $lookup{$element})
    {
        print "Exists";
    }

Заранее спасибо.

Ответы [ 7 ]

6 голосов
/ 21 апреля 2010

Вы хотите убедиться, что правильно сделали свой хэш. Очень устаревший chop - это не то, что вы хотите использовать. Вместо этого используйте chomp и используйте его сразу для всего массива, прежде чем создавать хеш:

 open my $fh, '<', 'list.txt' or die "unable to open list.txt: $!";
 chomp( my @data = <$fh> );
 my $hash = map { $_, 1 } @data;
2 голосов
/ 21 апреля 2010

С Perl 5.10 и выше вы также можете использовать оператор умного совпадения:

my $id = get_id_to_check_for();
open my $fh, '<', 'list.txt' or die "unable to open list.txt: $!";
chomp( my @data = <$fh> );
print "Id found!" if $id ~~ @data;
2 голосов
/ 21 апреля 2010

Ваша проблема в том, что chop возвращает прерывистый символ, а не результирующую строку, поэтому вы создаете хеш с одной записью для новой строки. Это было бы очевидно при отладке, если вы использовали Data :: Dumper для вывода результирующего хэша.

Попробуйте вместо этого:

my @data=<FILE>;
chomp @data;

my %lookup = map {$_ => undef} @data;
2 голосов
/ 21 апреля 2010

chop возвращает выбранный символ, а не то, что осталось позади. Возможно, вы хотите что-то вроде этого:

my %lookup = map { substr($_,0,-1) => undef } @data;

Однако, как правило, вы должны рассмотреть возможность использования chomp вместо chop для более интеллектуального удаления CRLF, так что в итоге вы получите такую ​​строку:

my %lookup =map {chomp; $_ => undef } @data;

2 голосов
/ 21 апреля 2010
0 голосов
/ 21 апреля 2010

Это может не совсем соответствовать вашей конкретной проблеме, но если ваши целые числа должны быть посчитал, вы могли бы даже использовать хорошее старый "канонический" подход perl:

 open my $fh, '<', 'list.txt' or die "unable to open list.txt: $!";

 my %lookup;
 while( <$fh> ) { chomp; $lookup{$_}++ }   # this will count occurences if ints

 my $element = '123';
 if( exists $lookup{$element} ) {
    print "$element $lookup{$element} times there\n" 
 }

В некоторых случаях это может быть даже быстрее, чем решения с промежуточным массивом.

Привет

БВУ

0 голосов
/ 21 апреля 2010

Это должно работать ... он использует first в List :: Util для выполнения поиска и исключает начальные map (это предполагает, что вам не нужно сохранять значения для чего-то другого сразу после) , chomp выполняется при поиске значения; см. perldoc -f chomp .

use List::Util 'first';
open (my $fh, 'list.txt') or die 'unable to open list.txt!';

my @elements = <$fh>;

my $element = '123';
if (first { chomp; $_ eq $element } @elements)
{
    print "Exists";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...