【问题标题】:How to validate values of an multi dimensional hash in perl?如何在 perl 中验证多维散列的值?
【发布时间】:2018-10-19 05:58:59
【问题描述】:

我有一个像这样的多维散列

%hash = {'5' => {'DS' => 'TESTD1',
                 'DN' => 'TESTD1',
                 'PP' => 'APPLE44'},
         '6'=> {'DS' => 'TESTD2',
                'DN' => 'TESTD2',
                'PP' => 'APPLE44'},
         '7'=>{'DS' => 'TESTD1',
               'DN' => 'TESTD3',
               'PP' => 'APPLE44'} 
         '8'=>{'DS' => 'TESTD1',
               'DN' => 'TESTD1',
               'PP' => 'ORANGE33' }
          };

现在我想检查整个 hash 的 'PP' 值和 'DS' 值之间是否存在唯一映射。 例如,第 7 个键不是唯一的,因为它与 DS 和 PP 值的第 5 个相同。 只有当 PP 和 DS 值相同时,我才应该增加计数。

到目前为止,我已经尝试使用 'exists',但似乎并没有按照我想要的方式工作,那么我们该如何实现呢?

【问题讨论】:

  • @xxfelixxx 我很抱歉,但是一些代码会让我更清楚
  • 好的,有一些代码:)

标签: perl hash hashmap


【解决方案1】:

您可能在使用 exists 时遇到了问题,因为您错误地定义了您的哈希值。当您应该使用 %hash = ( ... ) 创建散列或使用 $hash = { ... } 创建散列引用时,您执行 %hash = { ... }。阅读perldoc perlreftut 了解所有血腥细节。

使用另一个哈希来存储各种 DS / PP 组合并使用它来检查唯一性。

use warnings;
use strict;

my $hash = {
    '5' => {'DS' => 'TESTD1',
            'DN' => 'TESTD1',
            'PP' => 'APPLE44'},
    '6' => {'DS' => 'TESTD2',
            'DN' => 'TESTD2',
            'PP' => 'APPLE44'},
    '7' => {'DS' => 'TESTD1',
            'DN' => 'TESTD3',
            'PP' => 'APPLE44'}, 
    '8' => {'DS' => 'TESTD1',
            'DN' => 'TESTD1',
            'PP' => 'ORANGE33'},
};

my %check_for_dups;
for my $key ( sort keys %$hash ) {
    my $subhash = $hash->{ $key };
    my $combo = join '_', 'DS', $subhash->{ DS }, 'PP', $subhash->{ PP };
    $check_for_dups{ $combo }->{ $key } = 1;
}

my $found_dups = 0;
for my $combo ( sort keys %check_for_dups ) {
    my @keys_for_combo = sort { $a <=> $b } keys %{ $check_for_dups{ $combo } };
    if ( scalar @keys_for_combo > 1 ) {
        print "Duplicate keys for combo '$combo' : " . join(',',@keys_for_combo) . "\n";
        $found_dups = 1;
    }
}

print "All combos are unique!\n"
    unless $found_dups;

输出

Duplicate keys for combo 'DS_TESTD1_PP_APPLE44' : 5,7

【讨论】:

  • 当我发现重复项时,我尝试使用 count 而不是死掉,但由于某种原因它不起作用。它只是没有进入 'if' 循环
  • 要跟踪计数而不是死在第一个副本上,这需要更多的簿记......但是你去吧。
【解决方案2】:

成功了

 my %dup; 
 if(exists($dup{'DS'}{'PP'}))
 {
     count++;
 }

【讨论】:

  • 此代码无法回答您的问题。如果您有想要分享的有效解决方案,请分享,但请发布整个代码。
【解决方案3】:

我使用的答案与 xxfelixxx 几乎相同,但在他的代码中,当它找到第一个重复项时,我们无法找到所有重复项,因为脚本存在(实际上死了 :))。

因此我使用数组的哈希来存储重复的索引,所以你知道重复的索引和它们的计数(数组值的计数)

#!/usr/bin/perl
use strict;
use warnings FATAL => 'all';
my $hash = {'5' => {'DS' => 'TESTD1',
                 'DN' => 'TESTD1',
                 'PP' => 'APPLE44'},
         '6'=> {'DS' => 'TESTD2',
                'DN' => 'TESTD2',
                'PP' => 'APPLE44'},
         '7'=>{'DS' => 'TESTD1',
               'DN' => 'TESTD3',
               'PP' => 'APPLE44'},
         '8'=>{'DS' => 'TESTD1',
               'DN' => 'TESTD1',
               'PP' => 'ORANGE33' }
          };

my %result;
foreach (keys %{$hash}) {
   my $n_key = $hash->{$_}{'DS'} . '_' . $hash->{$_}{'PP'};
   if( ! defined $result{$n_key} ) {
      $result{$n_key} = [ $_ ];
   } else {
      push @{$result{$n_key}}, $_;
   }
}

foreach (keys %result) {
   if( @{$result{$_}} > 1 ) {
      my($DD, $PP) = split('_', $_);
      print "Duplicated values found for DD => $DD, PP => $PP, ";
      print "No of duplicates : ".scalar(@{$result{$_}})." and there respective indexes are @{$result{$_}}\n";
   }
}

print "$_ : @{$result{$_}}\n" foreach(keys %result);

输出

Duplicated values found for DD => TESTD1, PP => APPLE44, No of duplicates : 2 and there respective indexes are 7 5
TESTD2_APPLE44 : 6
TESTD1_ORANGE33 : 8
TESTD1_APPLE44 : 7 5

【讨论】:

  • 我需要使用计数。你的回答会产生好坏参半的结果
  • 你能用count回答吗?
  • 你应该use strict; use warnings 'all';
  • @Dada,感谢您提供宝贵的cmets,请找到它。
  • @Sherlock.H,没有重复的索引已经在数组中并且被打印了,你应该只计算数组元素。虽然我现在已经添加了。
猜你喜欢
  • 2010-09-14
  • 2020-12-11
  • 2011-12-13
  • 2015-07-17
  • 2018-12-07
  • 2021-07-11
  • 1970-01-01
  • 2011-02-15
  • 2021-08-15
相关资源
最近更新 更多