You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Perl中如何比对两个任意深度哈希的键结构,忽略值差异

嵌套哈希键结构比对实现方案

方案1:基于Test::Deep实现(推荐)

你可以通过一个简单的递归函数,自动将参考哈希的所有值替换为ignore()对象,即可实现仅校验键结构、忽略值比对的需求:

use Test::Deep;

# 递归将哈希所有值替换为ignore(),保留键结构
sub hash_structure {
    my ($hash_ref) = @_;
    my %struct;
    while (my ($k, $v) = each %$hash_ref) {
        $struct{$k} = ref $v eq 'HASH' ? hash_structure($v) : ignore();
    }
    return \%struct;
}

# 测试用例
my %hash1 = ( key1 => "foo", key2 => {key21 => "bar", key22 => "yeah"});
my %hash2 = ( key1 => "foo", key2 => {key21 => "bar", key22 => "wow"});

cmp_deeply(\%hash1, hash_structure(\%hash2), "键结构一致测试通过");
# 如果需要双向校验结构完全一致,再加一行反向校验即可
cmp_deeply(\%hash2, hash_structure(\%hash1), "双向校验键结构完全一致");

如果你的嵌套结构中可能包含数组,可扩展上述函数增加数组类型的判断逻辑,对应递归处理数组元素的结构即可。

方案2:无依赖独立递归校验函数

如果你不想依赖Test::Deep,也可以自己实现双向键结构校验,还可以自定义错误提示的键路径:

sub check_hash_key_structure {
    my ($hash1, $hash2, $path) = @_;
    $path //= '';

    # 先校验当前层级键数量一致
    my @keys1 = keys %$hash1;
    my @keys2 = keys %$hash2;
    return (0, "键数量不一致,路径$path 左侧有".@keys1."个键,右侧有".@keys2."个键") unless @keys1 == @keys2;

    # 校验所有键双向存在、嵌套结构类型一致
    for my $k (@keys1) {
        return (0, "键不存在:路径$path\->{$k} 仅左侧存在") unless exists $hash2->{$k};
        my $new_path = $path ? "$path\->{$k}" : "{$k}";
        # 如果值是哈希类型,递归校验下一层结构
        if (ref $hash1->{$k} eq 'HASH') {
            return (0, "类型不一致:路径$new_path 左侧是HASH,右侧不是") unless ref $hash2->{$k} eq 'HASH';
            my ($ok, $err) = check_hash_key_structure($hash1->{$k}, $hash2->{$k}, $new_path);
            return ($ok, $err) unless $ok;
        }
    }
    return (1, "键结构完全一致");
}

# 使用示例
my ($ok, $err) = check_hash_key_structure(\%hash1, \%hash2);
ok($ok, $err);

内容的提问来源于stack exchange,提问作者Matti Lattu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 21:45:03