【问题标题】:Merging of duplicate path values of a Perl HOH合并 Perl HOH 的重复路径值
【发布时间】:2021-04-19 17:51:52
【问题描述】:

我有一个 perl HOH(哈希散列),其中我有序列号 1,2,3.... 等等以及具有相关计数器值的目录路径。谁能建议一种方法,我可以将重复的内部路径(例如 /usr/lib , /bin/ )合并为一个新的哈希值并添加值?

HOH 示例:

$VAR1 = {
          '1' => {
                   '/usr/lib' => 18
                 },
          '3' => {
                   '/bin/' => '3'
                 },
          '4' => {
                   '/usr/lib' => 12
                 },
          '2' => {
                   '/bin/' => '6'
                 },
          '5' => {
                   '/dev/' => '2'
                 },
          '6' => {
                   '/tmp/' => '8'
                 }
        };

我正在寻找的最终输出要求是具有组合值的简单哈希。不需要序列号:

$VAR1 = {
              '/usr/lib' => '30',
              '/bin/' => '9',
              '/dev/' => '2',
              '/tmp/' => '8'
              
        };

【问题讨论】:

    标签: perl


    【解决方案1】:

    试试

    sub aggregate_counts {
        my $HOH = shift;
        my %out;
        for my $h (values %$HOH) {
            for my $k ( keys %$h) {
                $out{$k} += $h->{$k};
            }
        }
        \%out
    }
    

    使用像aggregate_counts($hoh) 这样的子例程来获取所需格式的哈希引用。

    完整的测试脚本:

    use strict;
    use warnings;
    sub aggregate_counts {
        my $HOH = shift;
        my %out;
        for my $h (values %$HOH) {
            for my $k ( keys %$h) {
                $out{$k} += $h->{$k};
            }
        }
        \%out
    }
    
    my
    $VAR1 = {
              '1' => {
                       '/usr/lib' => 18
                     },
              '3' => {
                       '/bin/' => '3'
                     },
              '4' => {
                       '/usr/lib' => 12
                     },
              '2' => {
                       '/bin/' => '6'
                     },
              '5' => {
                       '/dev/' => '2'
                     },
              '6' => {
                       '/tmp/' => '8'
                     }
            };
    
    
    use Data::Dumper;
    
    print Dumper(aggregate_counts($VAR1))
    

    输出:

    $VAR1 = {
              '/dev/' => '2',
              '/tmp/' => '8',
              '/bin/' => 9,
              '/usr/lib' => 30
            };
    

    【讨论】:

    • @ikegami 我修改了答案,牢记您的建议。您能否澄清何时触发了未初始化的值以及警告?我使用exists 来避免这种情况。
    • Post/pre-inc/dec,+= 和 -= 不关心。看起来 |= 和 ^= 也不是(但 &= 会)。
    【解决方案2】:

    这可以帮助你:

    use strict; use warnings;
    use Data::Dumper;
    
    my %hash = (
    '1' => {
           '/usr/lib' => 18
         },
    '3' => {
           '/bin/' => '3'
         },
    '4' => {
           '/usr/lib' => 12
         },
    '2' => {
           '/bin/' => '6'
         },
    '5' => {
           '/dev/' => '2'
         },
    '6' => {
           '/tmp/' => '8'
         }
    );
    
    my %result;
    
    foreach my $key (keys %hash){
        foreach my $inner (keys %{$hash{$key}}) {
            $result{$inner} += $hash{$key}{$inner};
        }
    }
    
    print Dumper(\%result);
    

    输出:

    $VAR1 = {
              '/usr/lib' => 30,
              '/bin/' => 9,
              '/dev/' => 2,
              '/tmp/' => 8
            };
    

    注意:请在问题中发布您的代码,同时在 SO 中寻求帮助。

    【讨论】:

      【解决方案3】:

      你不关心外部哈希的键。那么让我们从values(%$VAR1)开始:

      { '/usr/lib' => 18 },
      { '/bin/' => '3' },
      { '/usr/lib' => 12 },
      { '/bin/' => '6' },
      { '/dev/' => '2' },
      { '/tmp/' => '8' },
      

      散列非常适合分组。我们将遍历上面的列表,然后我们将遍历每个散列的元素,使用散列对它们进行分组。

      my %grouped;
      for my $inner (values(%$VAR1)) {
         for my $key (keys(%$inner)) {
            my $val = $inner->{$key};
            $grouped{$key} += $val;
         }
      }
      

      我们已经完成了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-11-28
        • 2011-05-10
        • 1970-01-01
        • 2022-07-04
        • 2018-04-07
        • 2018-07-07
        相关资源
        最近更新 更多