【问题标题】:Perl: Comparing 2 hash of arrays with another arrayPerl:将数组的 2 个哈希与另一个数组进行比较
【发布时间】:2012-08-21 07:51:31
【问题描述】:

我已经用 Perl 编写了下面的代码,但它没有给出理想的输出。我正在处理一个数组和两个数组哈希之间的比较。

给定示例输入文件:

1) file1.txt
   A6416    A2318
   A84665   A88

2) hashone.pl

%hash1=(
A6416=>['E65559', 'C11162.1', 'c002gnj.3',],
A88=>['E77522', 'M001103', 'C1613.1', 'c001hyf.2',],
A84665=>['E138347', 'M032578', 'C7275.1', 'c009xpt.3',],
A2318=>['E128591', 'C43644.1', 'C47705.1', 'c003vnz.4',],
);

3) hashtwo.pl

%hash2=(
15580=>['C7275.1', 'E138347', 'M032578', 'c001jnm.3', 'c009xpt.2'],
3178=>['C1613.1', 'E77522','M001103', 'c001hyf.2', 'c001hyg.2'],
24406=>['C11162.1', 'E65559', 'M003010', 'c002gnj.2'],
12352=>['C43644.1', 'C47705.1', 'E128591','M001458', 'c003vnz.3'],
);

我的目标是完成所描述的任务:

从file1.txt,我必须在%hash1中找到对应的ID。例如,A6416 (file1.txt) 是 %hash1 中的键。接下来,我必须在 %hash2 中找到 A6416 ['E65559', 'C11162.1', 'c002gnj.3',] 的值。如果在 %hash2 中找到大多数(超过 50%)值,我将 A6416 替换为 %hash2 中的相应键。

Example:
A6416 A2318 
A84665 A88

Output:
24406 12352
15580 3178

请注意,%hash1 和 %hash2 的键不同(它们不重叠)。但值是相同的(它们重叠)。

#!/usr/bin/perl -w
use strict;
use warnings;
open FH, "file1.txt" || die "Error\n";
my %hash1 = do 'hashone.pl';     
my %hash2 = do 'hashtwo.pl';  
chomp(my @array=<FH>);

foreach my $amp (@array)
{
    if ($amp =~ /(\d+)(\s?)/)
    {
        if (exists ($hash1{$1}))
        {
            for my $key (keys %hash2) 
            {
                for my $i ( 0 .. $#{ $hash2{$key} } ) 
                {
                    if ((@{$hash1{$1}}) eq ($hash2{$key}[$i]))
                    { 
                    print "$key";
                    }
                }
           }
        }
    }
}   
close FH;
1;

非常感谢任何有关此问题的指导。谢谢!

【问题讨论】:

    标签: arrays perl hash


    【解决方案1】:

    我认为您应该将%hash2 反转为这种结构:

    $hash2{'C7275.1'} = $hash2{'E138347'} = $hash2{'M032578'}
                      = $hash2{'c001jnm.3'} = $hash2{'c009xpt.2'} = 15580;
    $hash2{'C1613.1'} = $hash2{'E77522'} = $hash2{'M001103'}
                      = $hash2{'c001hyf.2'} = $hash2{'c001hyg.2'} = 3178;
    $hash2{'C11162.1'} = $hash2{'E65559'}
                       = $hash2{'M003010'} = $hash2{'c002gnj.2'} = 24406;
    $hash2{'C43644.1'} = $hash2{'C47705.1'} = $hash2{'E128591'}
                       = $hash2{'M001458'} = $hash2{'c003vnz.3'} = 3178;
    

    这样您就可以更有效地执行这些查找,而不必遍历%hash2 的每个元素

    【讨论】:

    • 感谢您的回复。我尝试使用 reverse() 函数来反转 %hash2。 %revhash=反向(%hash2);但它会产生错误。鉴于每个键都有多个值,有什么具体的方法可以做到吗?
    • 澄清一下,您是否创建了具有多个键和 1 个值的哈希结构?请让我知道,以便我可以进行相应的操作。
    • @zock:由于您的%hash2 的每个键都映射到一个数组引用,因此您不能只使用reverse。您需要编写一个循环:my %revhash; foreach my $key (keys %hash2) { foreach my $value (@{$hash2{$key}}) { $revhash{$value} = $key; } }.
    【解决方案2】:

    根据 ruakh 和 zock 的响应,这里是构建 hash2 查找表所需的代码

    #!/usr/bin/perl
    use strict;
    use warnings;
    use Data::Dumper;
    
    my %hash2=(
    15580=>['C7275.1', 'E138347', 'M032578', 'c001jnm.3', 'c009xpt.2'],
    3178=>['C1613.1', 'E77522','M001103', 'c001hyf.2', 'c001hyg.2'],
    24406=>['C11162.1', 'E65559', 'M003010', 'c002gnj.2'],
    12352=>['C43644.1', 'C47705.1', 'E128591','M001458', 'c003vnz.3'],
    );
    
    # Build LUT for hash2
    my %hash2_lut;
    foreach my $key (keys %hash2)
    {
        foreach my $val (@{$hash2{$key}})
        {
            $hash2_lut{$val} = $key
        }
    }
    
    print Dumper(\%hash2_lut);
    

    请选择 ruakh 的帖子作为答案,只是想为您澄清代码。使用Data::Dumper...它是你的朋友。

    这是输出:

    $VAR1 = {
          'C47705.1' => '12352',
          'M032578' => '15580',
          'E138347' => '15580',
          'E77522' => '3178',
          'C7275.1' => '15580',
          'c001jnm.3' => '15580',
          'E65559' => '24406',
          'C1613.1' => '3178',
          'M001458' => '12352',
          'c002gnj.2' => '24406',
          'c009xpt.2' => '15580',
          'c001hyf.2' => '3178',
          'C43644.1' => '12352',
          'E128591' => '12352',
          'c001hyg.2' => '3178',
          'M003010' => '24406',
          'c003vnz.3' => '12352',
          'C11162.1' => '24406',
          'M001103' => '3178'
        };
    

    【讨论】:

      猜你喜欢
      • 2016-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-13
      • 1970-01-01
      • 2019-03-03
      相关资源
      最近更新 更多