I have a file in which every line is an integer which represents an id. What 开发者_JAVA技巧I want to do is just check whether some specific ids are in this list. But the code didn't work. It never tells me it exists even if 123 is a line in that file. I don't know why? Help appreciated.
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";
}
Thanks in advance.
You want to ensure you make your hash correctly. The very outdated chop isn't what you want to use. Use chomp instead, and use it on the entire array at once and before you create the hash:
open my $fh, '<', 'list.txt' or die "unable to open list.txt: $!";
chomp( my @data = <$fh> );
my $hash = map { $_, 1 } @data;
With Perl 5.10 and up, you can also use the smart match operator:
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;
perldoc -q contain
chop
returns the character it chopped, not what was left behind. You perhaps want something like this:
my %lookup = map { substr($_,0,-1) => undef } @data;
However, generally, you should consider using chomp
instead of chop
to do a more intelligent CRLF removal, so you'd end up with a line like this:
my %lookup =map {chomp; $_ => undef } @data;
Your problem is that chop returns the character chopped, not the resulting string, so you're creating a hash with a single entry for newline. This would be obvious in debugging if you used Data::Dumper to output the resulting hash.
Try this instead:
my @data=<FILE>;
chomp @data;
my %lookup = map {$_ => undef} @data;
This should work... it uses first
in List::Util to do the searching, and eliminates the initial map
(this is assuming you don't need to store the values for something else immediately after). The chomp
is done while searching for the value; see 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";
}
This one may not exactly match your specific problem, but if your integer numbers need to be counted, you might even use the good old "canonical" perl approach:
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"
}
This might even be in some circumstances faster than solutions with intermediate array.
Regards
rbo
精彩评论