Perl CSV到本机阵列散列

n3schb8v  于 2022-11-30  发布在  Perl
关注(0)|答案(1)|浏览(147)

我正在尝试从一个只存储唯一键的csv文件构建一个关联数组。所有这些都没有使用额外的功能,如Text::CSV一个示例文本文件:

emp1,dept1,1090
emp2,dept2,8920
emp3,dept1,3213
emp3,dept2,3234

我希望按部门组织数据,看起来像

$hash = {
dept=>[dept1, dept2, dept3]
}

并且在每个部门内具有其各自的EMP和ID
到目前为止,我试过

my %hash;
    while (<$fh>){
        my @data = split(/,/, $fh);
        push @{$hash{$_}}, shift @data
            for qw(emp dept id);
    }

然而,这似乎并没有正确地填充数组,相反,只是初始化了没有数据的数组。我到处寻找如何做到这一点的例子,但我的搜索总是包含提到Text::CSV的人

afdcj2ne

afdcj2ne1#

你的第一个问题是这条线

my @data = split(/,/, $fh);

您正在拆分文件句柄,而不是从while语句返回的数据。它存储在$_
下面是修改代码以修复split行。我还使用内联的DATA文件句柄来使自己更容易。最后,我添加了对Data::Dumper的调用,以查看将什么存储到哈希中。

use Data::Dumper ;
my %hash;
    while (<DATA>){
        my @data = split(/,/, $_);
        push @{$hash{$_}}, shift @data
            for qw(emp dept id);
    }

print "Hash is " . Dumper(\%hash);
__DATA__
emp1,dept1,1090
emp2,dept2,8920
emp3,dept1,3213
emp3,dept2,3234

运行该命令将得到以下结果,这显示了第二个问题--您在id列中包含了一个换行符

Hash is $VAR1 = {
          'dept' => [
                      'dept1',
                      'dept2',
                      'dept1',
                      'dept2'
                    ],
          'emp' => [
                     'emp1',
                     'emp2',
                     'emp3',
                     'emp3'
                   ],
          'id' => [
                    '1090
',
                    '8920
',
                    '3213
',
                    '3234
'
                  ]
        };

通过在split行之前调用chomp来解决此问题

use Data::Dumper ;
my %hash;
    while (<DATA>){
        chomp;
        my @data = split(/,/, $_);
        push @{$hash{$_}}, shift @data
            for qw(emp dept id);
    }

print "Hash is " . Dumper(\%hash);
__DATA__
emp1,dept1,1090
emp2,dept2,8920
emp3,dept1,3213
emp3,dept2,3234

输出现在为

Hash is $VAR1 = {
          'id' => [
                    '1090',
                    '8920',
                    '3213',
                    '3234'
                  ],
          'emp' => [
                     'emp1',
                     'emp2',
                     'emp3',
                     'emp3'
                   ],
          'dept' => [
                      'dept1',
                      'dept2',
                      'dept1',
                      'dept2'
                    ]
        };

这样看起来更好,但是在hash中有重复的数据。

my %hash;
my @cols = qw( emp dept id);

while (<DATA>)
{
    chomp $_;
    my @data = split /,/, $_ ;

    for my $i (0 .. @cols-1)
    {
        # Store as a hash of hashes
        $hash{ $cols[$i] }{ $data[$i] } ++;
    }
}

print "Hash is " . Dumper(\%hash);

这样看起来更好-重复项已删除

Hash is $VAR1 = {
          'dept' => {
                      'dept2' => 2,
                      'dept1' => 2
                    },
          'emp' => {
                     'emp3' => 2,
                     'emp2' => 1,
                     'emp1' => 1
                   },
          'id' => {
                    '3213' => 1,
                    '8920' => 1,
                    '1090' => 1,
                    '3234' => 1
                  }
        };

您的要求是拥有数组的散列,因此添加最后一个步骤,将散列的散列转储为您需要的格式

my %result;
for my $col (keys %hash)
{
    push @{ $result{$col} }, sort keys %{ $hash{$col} } ; 
} 

print "Hash is " . Dumper(\%result);

输出这个

Hash is $VAR1 = {
          'dept' => [
                      'dept1',
                      'dept2'
                    ],
          'emp' => [
                     'emp1',
                     'emp2',
                     'emp3'
                   ],
          'id' => [
                    '1090',
                    '3213',
                    '3234',
                    '8920'
                  ]
        };

相关问题