比较两个数组的哈希值

时间:2016-09-22 12:22:36

标签: arrays perl hash

我有两个数组,哈希保存这些数组

 Array 1:
  my $group = "west"
  @{ $my_big_hash{$group} } = (1534,2341,2322,3345,689,3333,4444,5533,3334,5666,6676,3435);

 Array 2 :

   my $element = "Location" ;
   my $group  = "west" ;
   @{ $my_tiny_hash{$element}{$group} } =  (153,333,667,343);

现在我想比较

  

@ {$ my_tiny_hash {$ element} {$ group}}

  

@ {$ my_big_hash {$ group}}

并检查微小哈希数组的所有元素是否都是big_hash数组的一部分。  我们可以看到微小哈希只有3位元素,如果我们只比较前3位数字,所有这些元素都匹配大哈希

如果前三个数字/字母匹配并且所有数据都在大数组中可用,则其匹配或我们必须打印不匹配的元素

它是一个数组比较。  我们如何实现它。

PS:没有Array Utils,如何实现它

使用Array Utils的解决方案非常简单

my @minus = array_minus( @{ $my_tiny_hash{$element}{$group} } , @{ $my_big_hash{$group} }  );

但它比较了所有数字,我只想匹配前3位

希望这很清楚

由于

3 个答案:

答案 0 :(得分:7)

这似乎可以做你想要的。

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

my (%big_hash, %tiny_hash);
my $group = 'west';
my $element = 'Location';

# Less confusing initialisation!
$big_hash{$group} = [1534,2341,2322,3345,689,3333,4444,5533,3334,5666,6676,3435];
$tiny_hash{$element}{$group} = [153,333,667,343];

# Create a hash where the keys are the first three digits of the numbers
# in the big array. Doesn't matter what the values are.
my %check_hash = map { substr($_, 0, 3) => 1 } @{ $big_hash{$group} };

# grep the small array by checking the elements' existence in %check_hash
my @missing = grep { ! exists $check_hash{$_} } @{ $tiny_hash{$element}{$group} };

say "Missing items: @missing";

更新:另一种似乎更接近原始代码的解决方案。

my @truncated_big_array = map { substr($_, 0, 3) } @{ $big_hash{$group} };
my @minus = array_minus( @{ $my_tiny_hash{$element}{$group} } , @truncated_big_array );

答案 1 :(得分:2)

快速而有点脏的解决方案(扩展现有代码)。

#!/usr/bin/perl
use strict;
use warnings;
my (%my_big_hash, %my_tiny_hash, @temp_array);
my $group = "west";
@{ $my_big_hash{$group} } = (1534,343,2341,2322,3345,689,3333,4444,5533,3334,5666,6676,3435);
foreach (@{ $my_big_hash{$group} }){
    push @temp_array, substr $_, 0,3;
}
my $element = "Location";
my $group2  = "west";    
@{ $my_tiny_hash{$element}{$group2} } =  (153,333,667,343,698);


#solution below
my %hash = map { $_ => 1 } @temp_array;
foreach my $search (@{$my_tiny_hash{'Location'}->{west}}){
   if (exists $hash{$search}){
        print "$search exists\n";
   }
   else{
        print "$search does not exist\n";
   }
}

输出:

153 exists
333 exists
667 exists
343 exists
698 does not exist

Demo

另见:https://stackoverflow.com/a/39585810/257635

编辑:根据请求使用Array :: Utils。

foreach (@{ $my_big_hash{$group} }){
    push @temp_array, substr $_, 0,3;
}

my @minus = array_minus( @{ $my_tiny_hash{$element}{$group} } , @temp_array  );
print "@minus";

答案 2 :(得分:1)

另一种方法,使用有序比较而不是哈希:

@big = sort (1534,2341,2322,3345,689,3333,4444,5533,3334,5666,6676,3435);
@tiny =  sort (153,333,667,343,698);
for(@tiny){
  shift @big while @big and ($big[0] cmp $_) <0;
  push @{$result{ 
    $_ eq substr($big[0],0,3) 
    ? "found" : "missing" }},
    $_;
}

%result的内容:

{
      'found' => [
                   153,
                   333,
                   343,
                   667
                 ],
      'missing' => [
                     698
                   ]
}