有没有一种简单的方法来验证哈希元素比较的哈希值?

发布于 2024-12-17 07:21:11 字数 308 浏览 0 评论 0原文

有没有一种简单的方法来验证哈希元素比较的哈希值?

我需要验证哈希元素 $Table{$key1}{$key2}{K1}{Value} 的 Perl 哈希,与哈希中的所有其他元素进行比较,

第三个键将是 k1 到 kn,我想比较这些元素和其他键是相同的

if ($Table{$key1}{$key2}{K1}{Value} eq $Table{$key1}{$key2}{K2}{Value}
    eq  $Table{$key1}{$key2}{K3}{Value} ) 
{
   #do whatever
}

Is there a simple way to validate a hash of hash element comparsion ?

I need to validate a Perl hash of hash element $Table{$key1}{$key2}{K1}{Value} compare to all other elements in hash

third key will be k1 to kn and i want comprare those elements and other keys are same

if ($Table{$key1}{$key2}{K1}{Value} eq $Table{$key1}{$key2}{K2}{Value}
    eq  $Table{$key1}{$key2}{K3}{Value} ) 
{
   #do whatever
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

零崎曲识 2024-12-24 07:21:11

像这样的事情可能会起作用:

use List::MoreUtils 'all';

my @keys = map "K$_", 1..10;

print "All keys equal"
    if all { $Table{$key1}{$key2}{$keys[1]}{Value} eq $Table{$key1}{$key2}{$_}{Value} } @keys;

Something like this may work:

use List::MoreUtils 'all';

my @keys = map "K$_", 1..10;

print "All keys equal"
    if all { $Table{$key1}{$key2}{$keys[1]}{Value} eq $Table{$key1}{$key2}{$_}{Value} } @keys;
孤芳又自赏 2024-12-24 07:21:11

我会使用 Data::Dumper 来帮助完成这样的任务,特别是对于更一般的问题(其中第三个键比“K1”...“Kn”更任意)。使用 Data::Dumper 将数据结构字符串化,然后比较字符串。

use Data::Dumper;

# this line is needed to assure that hashes with the same keys output
# those keys in the same order.
$Data::Dumper::Sortkeys = 1;

my $string1= Data::Dumper->Dump($Table{$key1}{$key2}{k1});

for ($n=2; exists($Table{$key1}{$key2}{"k$n"}; $n++) {

    my $string_n = Data::Dumper->Dump($Table{$key1}{$key2}{"k$n"});

    if ($string1 ne $string_n) {
        warn "key 'k$n' is different from 'k1'";
    }

}

这可用于更一般的情况,其中 $Table{$key1}{$key2}{k7}{value} 本身包含复杂的数据结构。然而,当检测到差异时,它并不能帮助您找出差异在哪里。

I would use Data::Dumper to help with a task like this, especially for a more general problem (where the third key is more arbitrary than 'K1'...'Kn'). Use Data::Dumper to stringify the data structures and then compare the strings.

use Data::Dumper;

# this line is needed to assure that hashes with the same keys output
# those keys in the same order.
$Data::Dumper::Sortkeys = 1;

my $string1= Data::Dumper->Dump($Table{$key1}{$key2}{k1});

for ($n=2; exists($Table{$key1}{$key2}{"k$n"}; $n++) {

    my $string_n = Data::Dumper->Dump($Table{$key1}{$key2}{"k$n"});

    if ($string1 ne $string_n) {
        warn "key 'k$n' is different from 'k1'";
    }

}

This can be used for the more general case where $Table{$key1}{$key2}{k7}{value} itself contains a complex data structure. When a difference is detected, though, it doesn't give you much help figuring out where that difference is.

清风疏影 2024-12-24 07:21:11

相当复杂的结构。您应该考虑使用面向对象的编程技术。这将大大简化您的编程和这些复杂结构的处理。

首先,让我们简单一点。当你说:

$Table{$key1}{$key2}{k1}{value}

你真的是说:

my $value = $Table{$key1}->{$key2}->{k1};

或者

my $actual_value = $Table{$key1}->{$key2}->{k1}->{Value};

我会假设第一个。如果我错了,请告诉我,我会更新我的答案。

让我们简化一下:

my %hash = %{$Table{$key1}->{$key2}};

现在,我们只处理哈希。您可以使用两种技术:

  1. 按值对该哈希的键进行排序,然后如果两个键具有相同的值,它们将在排序列表中彼此相邻,从而轻松检测重复项。优点是所有重复的密钥将被打印在一起。缺点是这是一种需要时间和资源的排序。
  2. 反转哈希,因此它是按值作为键的,并且该键的值就是键。如果一个已经存在,我们就知道另一个键有重复的值。这比第一种技术更快,因为不涉及排序。但是,将检测到重复项,但不会将其打印在一起。

这是第一个技术:

my %hash = %{$Table{$key1}->{$key2}};
my $previous_value;
my $previous_key;
foreach my $key (sort {$hash{$a} cmp $hash{$b}} keys %hash) {
    if (defined $previous_key and $previous_value eq $hash{$key}) {
        print "\$hash{$key} is a duplicate of \$hash{$previous_key}\n";
    }
    $previous_value = $hash{$key};
    $previous_key = $key;   
}

第二个:

my %hash = %{$Table{$key1}->{$key2}};
my %reverse_hash;
foreach $key (keys %hash) {
   my $value = $hash{$key};
   if (exists $reverse_hash{$value}) {
       print "\$hash{$reverse_hash{$value}} has the same value as \$hash{$key}\n";
   }
   else {
       $reverse_hash{$value} = $key;
   }
}

A fairly complex structure. You should be looking into using object oriented programming techniques. That would greatly simplify your programming and the handling of these complex structures.

First of all, let's simplify a bit. When you say:

$Table{$key1}{$key2}{k1}{value}

Do you really mean:

my $value = $Table{$key1}->{$key2}->{k1};

or

my $actual_value = $Table{$key1}->{$key2}->{k1}->{Value};

I'm going to assume the first one. If I'm wrong, let me know, and I'll update my answer.

Let's simplify:

my %hash = %{$Table{$key1}->{$key2}};

Now, we're just dealing with a hash. There are two techniques you can use:

  1. Sort the keys of this hash by value, then if two keys have the same value, they will be next to each other in the sorted list, making it easy to detect duplicates. The advantage is that all the duplicate keys would be printed together. The disadvantage is that this is a sort which takes time and resources.
  2. Reverse the hash, so it's keyed by value and the value of that key is the key. If a key already exists, we know the other key has a duplicate value. This is faster than the first technique because no sorting is involved. However, duplicates will be detected, but not printed together.

Here's the first technique:

my %hash = %{$Table{$key1}->{$key2}};
my $previous_value;
my $previous_key;
foreach my $key (sort {$hash{$a} cmp $hash{$b}} keys %hash) {
    if (defined $previous_key and $previous_value eq $hash{$key}) {
        print "\$hash{$key} is a duplicate of \$hash{$previous_key}\n";
    }
    $previous_value = $hash{$key};
    $previous_key = $key;   
}

And the second:

my %hash = %{$Table{$key1}->{$key2}};
my %reverse_hash;
foreach $key (keys %hash) {
   my $value = $hash{$key};
   if (exists $reverse_hash{$value}) {
       print "\$hash{$reverse_hash{$value}} has the same value as \$hash{$key}\n";
   }
   else {
       $reverse_hash{$value} = $key;
   }
}
难得心□动 2024-12-24 07:21:11

解决这个问题的另一种方法是创建实用程序函数,如果所有键的某个函数返回的值相同,它将比较所有键:

sub AllSame (&\%) {
  my ($c, $h) = @_;
  my @k = keys %$h;
  my $ref;
  $ref = $c->() for $h->{shift @k};
  $ref ne $c->() and return for @$h{@k};
  return 1
}

print "OK\n" if AllSame {$_->{Value}} %{$Table{$key1}{$key2}};

但是如果您开始以这种方式思考,您会发现这种方法更加通用(推荐方式):

sub AllSame (@) {
  my $ref = shift;
  $ref ne $_ and return for @_;
  return 1
}

print "OK\n" if AllSame map {$_->{Value}} values %{$Table{$key1}{$key2}};

如果映射操作很昂贵,您可以制作相同的惰性对应项:

sub AllSameMap (&@) {
  my $c = shift;
  my $ref;
  $ref = $c->() for shift;
  $ref ne $c->() and return for @_;
  return 1
}

print "OK\n" if AllSameMap {$_->{Value}} values %{$Table{$key1}{$key2}};

如果您只想要键的某些子集,您可以使用哈希切片语法,例如:

print "OK\n" if AllSame map {$_->{Value}} @{$Table{$key1}{$key2}}{map "K$_", 1..10};

Alternative approach to the problem is make utility function which will compare all keys if has same value returned from some function for all keys:

sub AllSame (&\%) {
  my ($c, $h) = @_;
  my @k = keys %$h;
  my $ref;
  $ref = $c->() for $h->{shift @k};
  $ref ne $c->() and return for @$h{@k};
  return 1
}

print "OK\n" if AllSame {$_->{Value}} %{$Table{$key1}{$key2}};

But if you start thinking in this way you can found this approach much more generic (recommended way):

sub AllSame (@) {
  my $ref = shift;
  $ref ne $_ and return for @_;
  return 1
}

print "OK\n" if AllSame map {$_->{Value}} values %{$Table{$key1}{$key2}};

If mapping operation is expensive you can make lazy counterpart of same:

sub AllSameMap (&@) {
  my $c = shift;
  my $ref;
  $ref = $c->() for shift;
  $ref ne $c->() and return for @_;
  return 1
}

print "OK\n" if AllSameMap {$_->{Value}} values %{$Table{$key1}{$key2}};

If you want only some subset of keys you can use hash slice syntax e.g.:

print "OK\n" if AllSame map {$_->{Value}} @{$Table{$key1}{$key2}}{map "K$_", 1..10};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文