在哈希值

时间:2015-07-22 18:41:40

标签: perl hash

我正在创建一个将在csv文件中读取的预处理脚本,查看两个字段(P_ID和don_date),将两者连接在一起为我的哈希条目创建一个键,然后保留该行(拆分成数组)作为密钥的值。

如果文件中的另一行具有相同的p_id和don_date(它将匹配我的catted哈希键),我想获取您在代码中看到的其他值并将它们添加到现有哈希条目的值中。我正在进行一些测试,但我对于如何引用/解除引用以及所有在Perl(我是Python人员)中的工作感到困惑,因此每行都将具有唯一的P_ID / Don_Date值,否则它将汇总到现有值。

my @lineFields = ();
my %rollUpHash = ();

# Open file and loop through lines
#foreach my $line (<INFH>)
while(my $line = <INFH>)
  {
      # chomp($line);
      # print STDERR "New line in file\n";
      # <STDIN>;
      @lineFields = split(/,/, $line);

      # Pull out pertinent values for possible roll-up into a total
      my $p_id = $lineFields[18];
      my $don_date = $lineFields[19];
      my $nd_amt = $lineFields[14];
      my $deduct_amt = $lineFields[15];
      my $nondeduct_ytd = $lineFields[16];
      my $deduct_ytd = $lineFields[17];
      my $amount = $lineFields[24];
      my $anonymous = $lineFields[26];
      my $int_code_ex0003 = $lineFields[39];
      my $int_code_ex0006 = $lineFields[40];
      my $int_code_ex0028 = $lineFields[41];
      my $sumDeduct_NonDeduct_ytd = $deduct_ytd + $nondeduct_ytd;
      my $hashKey = $p_id . $don_date;
      # say "P_ID is $p_id\nDon_Date is $don_date\nND_Amt is $nd_amt\nDeduct_Amt is $deduct_amt\nNonDeduct_YTD is $nondeduct_ytd\nDeduct_YTD is $deduct_ytd\nAmount is $amount\nAnonymous is $anonymous\n0003 is $int_code_ex0003\n0006 is $int_code_ex0006\n0028 is $int_code_ex0028";
      # say "hashKey is $hashKey";
      # say "$sumDeduct_NonDeduct_ytd";

      if (exists($rollUpHash{$hashKey}))
        {
          say("Same key found, summing up!")
          $rollUpHash{$hashKey}[14] += $lineFields[14];
          $rollUpHash{$hashKey}[15] += $lineFields[15];
          $rollUpHash{$hashKey}[16] += $lineFields[16];
          $rollUpHash{$hashKey}[17] += $lineFields[17];
          $rollUpHash{$hashKey}[24] += $lineFields[24];
          push @{$rollUpHash{$hashKey}}, $sumDeduct_NonDeduct_ytd;
          # print %rollUpHash;
        }
      else
        {
          $rollUpHash{$hashKey} = \@lineFields;
        }
        foreach my $key (keys %rollUpHash)
        {
            print OUTFH "$key is @{$rollUpHash{$key}}";
        }

以下是三行清理输入数据:

152099-00001,,100,100,400,100,175,100,700,200,200,500,0,0,0,300,0,2575,105666,10/28/14,197800,23764962,"Jefferson,Mark",300,1004,N,N,N,D,Mike and Bonnie,Mike and Bonnie Gregorovitch,715 81st St NE,,,Central,IL,52402-7256,UNITED STATES,,,,,Y,soandso@email.com,,(888) 888-8888,"Jefferson,Mark",2222B,BASIC,,
342029-00015,,200,0,400,200,200,200,200,200,200,200,0,0,0,200,0,2000,3184444,09/27/14,197800,40949,"Macrow,Gregory",100,1004,N,N,N,D,John and Amber, John and Amber Meadows,PO Box 706,,,Logan,MD,01111-0704,UNITED STATES,,,,,Y,othersoandso@email,,(999) 999-9999,"Macrow,Gregory",2222B,BASIC,,
342029-00014,,200,0,400,200,200,200,200,200,200,200,0,0,0,200,0,2000,3184444,09/27/14,197800,22145,"Bartholomew,Vincent",100,1004,N,N,N,D,John and Amber, John and Amber Meadows,PO Box 706,,,Logan,MD,01111-0704,UNITED STATES,,,,,Y,othersoandso@email,,(999) 999-9999,"Bartholomew,Vincent",2222B,BASIC,,

任何有助于解决此问题的帮助都将非常感谢!

3 个答案:

答案 0 :(得分:2)

您不清楚自己想要对$sumDeduct_NonDeduct_ytd做什么:您真的想在线上添加新的金额,还是只用它替换最后一列?

此外,在包含带引号的逗号的CSV上使用split /,/是错误的。使用Text::CSV

#! /usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

use Text::CSV;

use constant {
    ND_AMT        => 14,
    DEDUCT_AMT    => 15,
    NONDEDUCT_YTD => 16,
    DEDUCT_YTD    => 17,
    PID           => 18,
    DON_DATE      => 19,
    AMOUNT        => 24,
};


my $csv = 'Text::CSV'->new({ binary => 1 });

my %hash;
open my $IN, '<:encoding(utf-8)', shift or die $!;
while (my $row = $csv->getline($IN)) {
    my $key = join ':', @{$row}[PID, DON_DATE];
    if (exists $hash{$key}) {
        $hash{$key}[$_] += $row->[$_] for ND_AMT, DEDUCT_AMT, NONDEDUCT_YTD,
                                          DEDUCT_YTD, AMOUNT;
        my $sum = $row->[DEDUCT_YTD] + $row->[NONDEDUCT_YTD];
        $hash{$key}[-1] = $sum;      # Or do you mean something else?
    } else {
        $hash{$key} = $row;          # You can store the reference directly,
    }                                # as you get a fresh new one for each iteration.
}

for my $key (keys %hash) {
    say "$key : @{ $hash{$key} }";   # You should rather use $csv->print.
}

答案 1 :(得分:1)

您将指向变量@lineFields的指针存储在rollUpHash哈希中,但它是同一个变量。因此,您最终会得到哈希值,其中所有值都是指向同一个数组的指针,您反复销毁该内容并填充其他内容。这没有意义。您必须在my @lineFields周期内移动while或更改行

$rollUpHash{$hashKey} = \@lineFields;

$rollUpHash{$hashKey} = [@lineFields];

答案 2 :(得分:0)

这有不同的问题:

当键不重复时,首先解决问题

  1. 您的foreach print语句处于while循环中。
  2. 我打印输出,这很奇怪。 3行输入提供4行输出(添加更多新行以查看)

    我将帮助修复其他问题作为更新