あるグループ内の別のグループ内の 1 つのデータであるという質問を取得するたびに(そして、それらがかなり出てくる場合は、ハッシュの観点から考える必要があります。
ハッシュはキー付きルックアップです。たとえば、ファイル #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";
}
}
それがどれほどうまく機能するかを見てください。唯一の問題は、ファイル #2 にはない電話番号がファイル #1 に含まれている可能性があることです。これは、ファイル #2 のすべての電話番号に対して 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;
次に、keys を使用してキーを一覧表示し、それらを調べます。%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
、および の3 つのハッシュがあり%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";
}
この例では、existsを使用してキーがハッシュに存在するかどうかを確認していないことに注意してください。つまり、単純にif ( $phone_hash2{$phone} )
代わりにif ( exists $phone_hash2{$phone} )
. 最初の形式は、キーが定義されているかどうかを確認します。値が NULL 文字列または数値のゼロであっても同様です。
2 番目の形式は、値が 0、null 文字列、または未定義でない限り true になります。意図的にハッシュの値を に設定したので、1
この形式を使用できます。exists
有効な値が NULL 文字列またはゼロである可能性がある状況があるため、これを使用するのは良い習慣です。ただし、可能な場合は使用せずにコードを読み取る方法を好む人もいますexists
。