每当您在另一组类型的问题中得到一个是一组中的一条数据时(并且它们出现了很多,您应该从散列的角度来考虑。
哈希是键控查找。假设您创建了一个哈希键,例如...我不知道...从文件#1中获取的电话号码。如果您读取文件 #2 中的一行,只需查看哈希值即可轻松查看它是否在文件 #1 中。快速、高效。
use strict; #ALWAYS ALWAYS ALWAYS
use warnings; #ALWAYS ALWAYS ALWAYS
use autodie; #Will end the program if files you try to open don't exist
# Constants are a great way of storing data that is ...uh... constant
use constant {
FILE_1 => "a1.txt",
FILE_2 => "a2.txt",
};
my %phone_hash;
open my $phone_num1_fh, "<", FILE_1;
#Let's build our phone number hash
while ( my $phone_num = <$phone_num1_fh> ) {
chomp $phone_num;
$phone_hash{ $phone_num } = 1; #Doesn't really matter, but best not a zero value
}
close $phone_num1_fh;
#Now that we have our phone hash, let's see if it's in file #2
open my $phone_num2_fh, "<", FILE_2;
while ( my $phone_num = <$phone_num2_fh> ) {
chomp $phone_num;
if ( exists $phone_hash { $phone_num } ) {
print "$phone_num is in file #1 and file #2";
}
else {
print "$phone_num is only in file #2";
}
}
看看效果如何。唯一的问题是文件#1 中可能有电话号码不在文件#2 中。您可以通过简单地为文件 #2 中的所有电话号码创建第二个哈希来解决此问题。
让我们用两个哈希再做一次:
my %phone_hash1;
my %phone_hash2;
open my $phone_num1_fh, "<", FILE_1;
while ( my $phone_num = <$phone_num1_fh> ) {
chomp $phone_num;
$phone_hash1{ $phone_num } = 1;
}
close $phone_num1_fh;
open my $phone_num2_fh, "<", FILE_2;
while ( my $phone_num = <$phone_num2_fh> ) {
chomp $phone_num;
$phone_hash2{ $phone_num } = 1;
}
close $phone_num1_fh;
现在,我们将使用键来列出键并遍历它们。当手机在两个哈希中时,我将创建一个%in_common
哈希
my %in_common;
for my $phone ( keys %phone_hash1 ) {
if ( $phone_hash2{$phone} ) {
$in_common{$phone} = 1; #Phone numbers in common between the two lists
}
}
现在,我有三个哈希%phone_hash1
、%phone_hash2
和%in_common
。
for my $phone ( sort keys %phone_hash1 ) {
if ( not $in_common{$phone} ) {
print "Phone number $phone is only in the first file\n";
}
}
for my $phone ( sort keys %phone_hash2 ) {
if ( not $in_common{$phone} ) {
print "Phone number $phone is only in " . FILE_2 . "\n";
}
}
for my $phone ( sort keys %in_common ) {
print "Phone number $phone is in both files\n";
}
请注意,在此示例中,我没有使用存在来查看密钥是否存在于哈希中。也就是说,我只是简单地if ( $phone_hash2{$phone} )
把if ( exists $phone_hash2{$phone} )
. 第一种形式检查是否定义了键——即使值是空字符串或数字为零。
只要值不为零、空字符串或未定义,第二种形式就为真。由于我故意将哈希值设置为1
,因此我可以使用这种形式。这是一个好习惯,exists
因为在某些情况下有效值可能是空字符串或零。但是,有些人喜欢在可能的情况下不使用代码读取exists
的方式。