Как я могу сравнить два набора хеш-ссылок, используя Perl? - PullRequest
0 голосов
/ 01 ноября 2010

Итак, у меня есть два файла с похожей информацией.

ПРИМЕРЫ

test.txt
1 = 1
2 = 2
3 = 3

test_2.txt
1 = 1
2 = 4
3 = 5
4 = 4
5 = 5
6 = 6

Теперь я хочу напечатать ключи и значения каждого хэша.

my %hash1;  
my $scalar_value1;  
my $scalar_value2;  
my $file = "/test/test.txt";  
open (TEST, "<$file") or die "$!";  
while (TEST) {  
            ($scalar_value1, $scalar_value2) = split( '=' );  
            $hash1{$scalar_value1}{'value1'} = $scalar_value1;  
            $hash1{$scalar_value1}{'value2'} = $scalar_value2;  
        }  
close TEST;  

foreach my $scalar_value1 (sort keys %hash1) {  
        print "$hash1{$scalar_value1}{'value1'} | $hash1{$scalar_value1}{'value2'}";  
}  


my %hash2;  
my $scalar_value_1_2;  
my $scalar_value_2_2;  
my $file_2 = "/test/test2.txt";  
open (TEST_2, "<$file_2") or die "$!";  
while (TEST_2) {  
            ($scalar_value_1_2, $scalar_value_2_2) = split( '=' );  
            $hash1{$scalar_value_1_2}{'value_1_2'} = $scalar_value_1_2;  
            $hash1{$scalar_value_1_2}{'value_2_2'} = $scalar_value_2_2;  
        }  
close TEST_2;  

foreach my $scalar_value_1_2 (sort keys %hash1) {  
        print "$hash1{$scalar_value_1_2}{'value1_2'} | $hash1{$scalar_value_1_2}{'value1_2'}";  
}    

Теперь, как я могу сравнить два хеша, чтобы получить новое значение, основываясь на том, содержал ли первый хеш похожий ключ?

if ($hash1{$scalar_value_1_2}{'value1_2} eq $hash1{$scalar_value1}{'value1'}) {  
    my $scalar_value_2_2; = $hash1{$scalar_value1}{'value2'};  
    print "YES MATCH: $scalar_value_2_2\n";  
} else {  
    print "N0 MATCH: $scalar_value_2_2\n";  
}  

Ответы [ 2 ]

1 голос
/ 02 ноября 2010

Похоже на простую задачу пересечения множества.Вот измененная версия кода с использованием работы Александра.

use strict;
use warnings;
sub read_hash {
    my $fname = shift;
    open (my $fh, "<",$fname) or die "$!";  
    my %hash;
    while (<$fh>) {
        chomp;
        my ($key,$value)=split /=/;
        $hash{$key}=$value;
    }
    # let's retrun the reference here. With big hashes, you want to avoid copying
    return \%hash;
}

my $h1=read_hash("test.txt");
my $h2=read_hash("test1.txt");

map {print "$_ = $h1->{$_}\n"} sort keys %$h1;
map {print "$_ = $h2->{$_}\n"} sort keys %$h2;

map {print "key from h1 $_ exists in h2\n" if exists $h2->{$_} } sort keys %$h1; 

# if you just want to take out the items from $h2 that also exists in $h1.
my %h3 = map {$_=>$h2->{$_} if exists $h2->{$_}} keys %$h1;

Обратите внимание, что программа использует map для выполнения итерации списка.Последнее использование карты создает хеш, который содержит пересечение ключей 2 хешей.Для дальнейшей оптимизации кода я бы перебрал хеш с меньшим количеством ключей.Также обратите внимание, что описанные выше методы не проверяют значение ключей.Он сравнивает только сами ключи.

Надеюсь, это поможет.

1 голос
/ 01 ноября 2010

Я переписал вашу программу для большей наглядности. "chomp" важно включить для удаления новой строки.

use strict;
use warnings;
sub read_hash {
    my $fname = shift;
    open (my $fh, "<",$fname) or die "$!";  
    my %hash;
    while (<$fh>) {
        chomp;
        my ($key,$value)=split /=/;
        $hash{$key}=$value;
    }
    return %hash;
}

my %hash1=read_hash("test.txt");

foreach my $key (sort keys %hash1) {  
        print "$key = $hash1{$key}\n";
}  

my %hash2=read_hash("test1.txt");

foreach my $key (sort keys %hash2) {  
        print "$key = $hash2{$key}\n";
}  


#------------------------

foreach my $key (sort keys %hash2) {  
        if (exists $hash1{$key}) {
            print "$key exists in first hash\n";
        } else {
            print "$key does not exist in first hash\n";
        }
}  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...