【问题标题】:Compare two hash of arrays比较两个数组哈希
【发布时间】:2016-09-22 12:22:36
【问题描述】:

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

 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} }

并检查小散列数组的所有元素是否都是大散列数组的一部分。 正如我们所见,小散列只有 3 位元素,如果我们只比较前 3 位,所有这些元素都与大散列匹配

如果前 3 个数字/字母匹配并且在大数组中都可用,那么它的匹配或我们必须打印不匹配的元素

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

PS:没有Array Utils,如何实现

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

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

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

希望这很清楚

谢谢

【问题讨论】:

  • 根据您编辑的问题。澄清match the first 3 digits
  • @ChankeyPathak "153 of tiny hash" 是 "1534 of big hash" 的一部分。另外,它是原始问题的一部分,我刚刚使用 Array Utils 发布了代码
  • 好的,已编辑相同的答案。我使用了一个包含大哈希前 3 位数字的临时数组,然后用它与 tiny 进行比较。
  • @ChankeyPathak:我们能否使用 Array Utils 将相同的逻辑扩展到单线解决方案。正如我所说,这一个班轮正在计算所有数字,我只对 3 个感兴趣
  • 是的,请参阅我编辑的答案。使用相同的方法。

标签: arrays perl hash


【解决方案1】:

这似乎是你想要的。

#!/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 );

【讨论】:

  • 逻辑和你的一样。我的只是有点简洁:-)
  • 感谢您的解决方案。
【解决方案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";

【讨论】:

  • 感谢您的解决方案。
  • 不客气。确保您下次以正确的格式发布清晰的问题,以便乍一看更容易理解。
【解决方案3】:

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

@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
                   ]
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-11
    相关资源
    最近更新 更多