Perl, сравнение хэшей, подмножество - PullRequest
3 голосов
/ 08 декабря 2011

Мне было интересно, есть ли какие-нибудь простые алгоритмы для сравнения, чтобы увидеть, является ли один хеш подмножеством другого хеша.

Например, если

$HASH{A} = B;
$HASH{B} = C;
$HASH{C} = D;

$HASH2{A} = B;
$HASH2{B} = C;

тогда% HASH2 является подмножеством% HASH.

Ответы [ 2 ]

4 голосов
/ 08 декабря 2011

При этом используются «интеллектуальное сопоставление» (~~) и List::Util::first

use 5.010;
use List::Util qw<first>;

sub hash_is_subset { 
    my ( $hash, $cand ) = @_;
    return not defined( first { not $hash->{ $_ } ~~ $cand->{ $_ } } keys %$cand );
}

hash_is_subset( \%HASH, \%HASH2 );
2 голосов
/ 08 декабря 2011

Предполагая, что ваши хеши просты (например, они не содержат ссылок в качестве значений), вы можете сделать это с помощью простого цикла:

sub is_subset {
    my ($h1, $h2) = @_;

    while (my ($k, $v) = each %$h1) {
        exists $h2->{$k} && $v eq $h2->{$k}
            or return;   # in case of list context, thanks davorg
    }
    return 1;
}

На английском языке, который проходит через каждый ключ, пара значений впервый хеш и спрашивает (а) является ли ключ во втором хеш-коде и (б), если да, значения одинаковы?Если он находит тот, который не существует, то первый хеш не является подмножеством второго хеша.В противном случае, это так.

Если ваши хеши более сложные, например, значение может быть хеш-значением, то сначала вам нужно лучше определить «подмножество» (например, { a => 1 } это подмножество { h2 => { a => 1 } }) и, вероятно, используйте некоторую рекурсию (или проверьте CPAN).

...