perl - 在perl中比较多维哈希的最佳方法

标签 perl hash

我想编写一个脚本,可以比较两个多维哈希,看看它们是否匹配。这两个哈希具有相同的键值,比较将成对进行,意味着从 $j=0 开始,先比较 $line[0] $line[1] 然后接下来是$line[2] $line[3]

$hash{"key"}{$key}{"$row $col"}= "$line[$j] $line[$j+1]";
$hash1{"key"}{$key1}{"$row1 $col1"}="$line1[$j] $line1[$j+1]";

我的 $line 和 $line1 取自一个大文件,并将逐行处理该大文件。例如:

@line = 1 2 3 4 5 6 7 8 #fst line from file1
@line1 = 1 2 3 3 4 5 6 7 7 #fst line from file2

$key$key1匹配时,脚本将继续比较$row $col,最后比较$line [$j] $line[$j+1]。我正在尝试使用之前类似问题中提到的模块 Test::More 之一,但它只能比较第一个不匹配的模块,并且输出采用默认格式。

not ok 1 - data structures should be the same
#   Failed test 'data structures should be the same'
#   at hash_check1.pl line 80.
#     Structures begin differing at:
#          $got->{key}{100}{2 3} = '62 19'
#     $expected->{key}{100}{2 3} = '12 24'
# Tests were run but no plan was declared and done_testing() was not seen.

比较这种类型的多维哈希的最佳方法是什么?

8月22日已编辑

如果 Test::More 模块能够比较两个哈希的所有 $key 匹配,我也可以这样做,但如果我可以输出匹配和非匹配以我自己喜欢的格式进行匹配会很棒。例如我想输出像

$key at $row $col no match with value $line[$j] $line[$j+1] ( expected value $line1[$j] $line1[$j+1] )

8月22日已编辑

下面是我的代码的一部分

use strict;
use warnings;
use Test::More;

open ( FILE1 , '<', "file.txt" ) or die $!;
open ( FILE2 , '<' , "file1.txt" ) or die $!;

chomp (my @file1 = <FILE1>);
chomp (my @file2 = <FILE2>);
my %hash=();
my %hash1=();

for ( $i =0 ; $i<=511 ; $i++ ) {
    my @line = split(" ",$file1[$i]);
    my @line1 = split(" ",$file2[$i]);
    my $key = ($i+1)*10;
    my $key1 = ($i+2)*10;

    for ( $j=0; $j<=15 ; $j+=2){
          my $col = hex($j);
          my $col1 = hex($j+1);
          $hash{"key"}{$key}{"$row $col1"}= "$line[$j] $line[$j+1]";
          $hash1{"key"}{$key1}{"$row1 $col1"}= "$line1[$j] $line1[$j+1]";
    }
}

##############comparison part start here###################
is_deeply(\%hash, \%hash1, 'data structures should be the same'); #can only print one mismatch

################Any better way?###########

最佳答案

这是一个将嵌套哈希值与字符串值进行比较的示例:

#! /usr/bin/env perl

use feature qw(say);
use warnings;
use strict;

my %hash;
my %hash1;

$hash{"key"}{A}{"2 3"}= "1 2";
$hash1{"key"}{A}{"2 3"}="2 3";
$hash{"key"}{B}{"2 3"}= "1 2";
$hash1{"key"}{C}{"2 3"}="2 3";

compare(\%hash, \%hash1);

sub compare {
    return _compare( @_, "" );
}

sub get_key_str { return $_[0] . '{' . $_[1] . '}' }

sub _process_key {
    my ( $h1, $h2, $info, $key, $str1, $str2 ) = @_;

    if ( exists $h2->{$key} ) {
        my $val1 = $h1->{$key};
        my $val2 = $h2->{$key};
        if ( ref $val1 eq "HASH" and ref $val2 eq "HASH" ) {
            _compare( $val1, $val2, get_key_str( $info, $key ) );
        }
        else {
            die "Expected string value" if ref $val1 or ref $val2;
            if ( $val1 ne $val2 ) {
                say "Value '$val1' in $str1 hash for key " . get_key_str( $info, $key )
                  . " does not match value '$val2' in $str2 hash";
            }
        }
    }
    else {
        my $cur_key = get_key_str( $info, $key );
        say "Got key $cur_key in $str1 hash, but missing in $str2 hash"; 
    }
}


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

    my %processed_keys;
    for (keys %$h1) {
        _process_key( $h1, $h2, $info, $_, "first", "second" );
        $processed_keys{$_}++;
    }
    for (keys %$h2) {
        next if exists $processed_keys{$_};
        _process_key( $h2, $h1, $info, $_, "second", "first" );
    }
}

输出:

Got key {key}{B} in first hash, but missing in second hash
Value '1 2' in first hash for key {key}{A}{2 3} does not match value '2 3' in second hash
Got key {key}{C} in second hash, but missing in first hash

关于perl - 在perl中比较多维哈希的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45809397/

相关文章:

ruby - 在每个值都是数组的哈希中,如何使用数组项查找键?

regex - 有没有办法匹配句子中所有相邻的单词?

perl - DateTime -> set_time_zone(...) 使用世界时区字符串,用于丢失的城镇

perl - 为什么我的 Perl CGI 程序显示的是程序代码,而不是输出?

Ruby - 如何将大型多维哈希数组转换为 CSV 格式

c - C 中的行很奇怪

arrays - Perl 将哈希值数组输出为表

perl - 更新终端上的多行 perl 输出

javascript - 从两个不同的值创建一个公共(public)键,不考虑顺序

dictionary - 为什么 `additionalProperties` 是 Swagger/OpenAPI 2.0 中表示 Dictionary/Map 的方式