2013-12-13 1 views
3

Есть ли модуль или лучший способ сравнить 2 хэша на основе ключей, а также получить и распечатать значения, отсутствующие в 1-м и 2-м хэшах?Perl сравнить два хэша на основе ключей и получить значения, отсутствующие в

У меня есть два хэша, которые описывают конкретную конфигурацию.
Я хочу сравнить два исторических состояния конфигурации. В частности, мне интересно узнать, какой ключ был удален и какой ключ был добавлен. Нет необходимости знать, где был отредактирован ключ (т. Е. Этого не происходит).

Пример:

Hash 1 keys: 
aaa 
bbb 
ccc 
ddd 

Hash 2 keys: 
aaa 
xxx 
bbb 
ccc 
yyy 

Результат должен быть что-то вроде:

xxx added 
ddd deleted 
yyy added 

Любая идея?

+0

Проверить это http://stackoverflow.com/questions/6978799/comparing-two-hashes-with-the-keys-and-values ​​ – PseftiS

ответ

0

Итератеть через все keys хеша 1. Для каждой проверки уберите его exists в хэш 2. Если нет, он был удален. Если это так, delete ключевой вид хеша 2. После этого все оставшиеся keys в хэш-2 - это те, которые были добавлены.

Редактировать: Я предполагаю, что вы знаете, как писать код на Perl и просто нужна идея. Если ответ звучит странно, посмотрите слова, написанные like this в Perldoc.

0
use warnings; 
use strict; 

my @array1 = qw (aaa bbb ccc ddd); 
my @array2 = qw(aaa xxx bbb ccc yyy); 
my (%hash1, %hash2); 

@hash1{@array1} = 1; 
@hash2{@array2} = 1; 

foreach (keys %hash2){ 
    print "added $_\n" unless exists $hash1{$_}; 
} 

foreach (keys %hash1){ 
    print "removed $_\n" unless exists $hash2{$_}; 
} 

печатает:

added xxx 
added yyy 
removed ddd 
+0

отлично работает, большое спасибо! – user3098583

+0

@ пользователь3098583 без проблем. Вы должны выбрать ответ как правильный, если он достигнет того, что вы хотели – fugu

2

Вы можете использовать List::Compare для выполнения этой задачи:

use strict; 
use warnings; 
use List::Compare; 

my %hash1 = map { $_ => undef } qw/aaa bbb ccc ddd/; 
my %hash2 = map { $_ => undef } qw/aaa xxx bbb ccc yyy/; 

my $lc = List::Compare->new([ keys %hash1 ], [ keys %hash2 ]); 

my @hash1Only = $lc->get_Lonly; 
my @hash2Only = $lc->get_Ronly; 

print "Added: @hash2Only\nDeleted: @hash1Only\n"; 

Выход:

Added: xxx yyy 
Deleted: ddd 

Надеется, что это помогает!

2
sub compare { 
    my ($a, $b) = @_; 
    [grep !exists $b->{$_}, keys %$a], [grep !exists $a->{$_}, keys %$b]; 
} 

my @keys1 = qw(aaa bbb ccc ddd); 
my @keys2 = qw(aaa xxx bbb ccc yyy); 
my (%hash1, %hash2); 
@hash1{@keys1}=(); 
@hash2{@keys2}=(); 
my ($deleted, $added) = compare(\%hash1, \%hash2); 
print "Added: @$added, Deleted: @$deleted\n"; 
+0

Приятный и простой. Будет ли это работать для многомерного массива? то есть my @ keys1 = ( ["11-AA", "11", "AA", "1.0", "98.375", "48.375", "0.0", "0.0",], ["22- BB "," 22 "," BB "," 1.0 "," 97.375 "," 58.375 "," 0.0 "," 0.0 ",],); – Wavesailor

Смежные вопросы