perl,比较哈希,子集

perl,比较哈希,子集,perl,hash,subset,Perl,Hash,Subset,我想知道是否有任何简单的算法可以比较,看看一个散列是否是另一个散列的子集 例如,如果 $HASH{A} = B; $HASH{B} = C; $HASH{C} = D; $HASH2{A} = B; $HASH2{B} = C; 然后%HASH2是%HASH的子集。假设您的HASH很简单(例如,它们不包含作为值的引用),您可以通过一个简单的循环来实现这一点: sub is_subset { my ($h1, $h2) = @_; while (my ($k, $v) = e

我想知道是否有任何简单的算法可以比较,看看一个散列是否是另一个散列的子集

例如,如果

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

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

然后%HASH2是%HASH的子集。

假设您的HASH很简单(例如,它们不包含作为值的引用),您可以通过一个简单的循环来实现这一点:

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)第二个散列中的键是不是,以及(b)如果是,值是否相同?如果它发现一个不是,那么第一个散列就不是第二个散列的子集。否则,它就是

如果您的哈希更复杂,例如,值可能是hashref,那么您首先需要更好地定义“子集”(例如,is
{a=>1}
{h2=>{a=>1}}
的子集),并且可能使用一些递归(或检查CPAN)。

这使用(
~
)和

使用5.010;
使用列表::Util qw;
子散列_是_子集{
我的($hash,$cand)=@;
返回未定义(第一个{not$hash->{$\u}~~$cand->{$\u}}键%$cand);
}
hash_是_的子集(\%hash,\%HASH2);

你是说
$HASH2{A}
而不是
$HASH1{A}
?@MattFenwick:可能——我已经把它修好了。戈登,如果我弄错了,请随时恢复我的编辑。@MattFenwick:好吧,如果你知道值是数字,我会将
eq
改为
==
@MattFenwick智能匹配运算符适用于字符串或整数
$a~~$b
可能最好使用裸
返回值来代替
返回值0
。以防函数在列表上下文中被调用。以前从未听说过智能匹配。谢谢你的提醒!聪明的匹配可以带来惊喜。例如,
{a=>“hello”}
{a=>qr/}
的子集吗?聪明的对手说是的,我很确定。
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 );