【问题标题】:Perl Hashes of Arrays and Some issues数组的 Perl 哈希和一些问题
【发布时间】:2014-08-05 14:08:05
【问题描述】:

我目前有一个如下所示的 csv 文件:

a,b
a,d
a,f
c,h
c,d

所以我将它们保存到一个哈希中,这样键“a”是一个带有“b,d,f”的数组,而键“c”是一个带有“h,d”的数组......这就是我用于:

while(<$fh>)
{
 chomp;
 my @row = split /,/;
 my $cat = shift @row;
 $category = $cat      if (!($cat eq $category))  ;
 push @{$hash{$category}}, @row;
}

close($fh);

不确定效率,但是当我进行数据转储时它似乎可以工作......

现在,我遇到的问题是;我想为每个键创建一个新文件,并且在每个文件中我想打印键中的每个元素,如下所示:

文件“a”看起来像这样:

b
d
f

<end of file>

有什么想法吗?我尝试过的一切都不起作用,我对哈希不太熟悉/经验丰富......

提前致谢:)

【问题讨论】:

  • @ikegami 只是个人喜好......这就是我想说的“如果第一列发生变化,请创建一个新键”。我确信有更方便的方法可以做到这一点,但效率并不是我担心的问题
  • 它不会创建新密钥。它只是做一个无用的副本。谁说效率? (对于可能正在阅读的其他人,评论是关于my $category = ...; 是写my $cat = ...; if (!($cat eq $category)) { $category = $cat; } 的更好方式。我在举例说明后删除了。)
  • @andrejr:为了清晰起见,通常将if not... 写成unless 会更好,因此您的声明将变为$category = $cat unless $category eq $cat
  • 很多人讨厌unless。使用它并不常见。此外,这里完全没有必要。不仅因为整个语句是有害的不需要,还因为它可以写成if $cat ne $category

标签: arrays perl hash


【解决方案1】:

使用each迭代器的输出过程非常简单,它在一次调用中为下一个哈希元素提供键值对

use strict;
use warnings;
use autodie;

open my $fh, '<', 'myfile.csv';

my %data;

while (<$fh>) {
   chomp;
   my ($cat, $val) = split /,/;
   push @{ $data{$cat} }, $val;
}

while (my ($cat, $values) = each %data) {
   open my $out_fh, '>', $cat;
   print $out_fh "$_\n" for @$values;
}

【讨论】:

    【解决方案2】:
    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    my %foos_by_cat;
    
    {
       open(my $fh_in, '<', ...) or die $!;
       while (<$fh_in>) {
          chomp;
          my ($cat, $foo) = split /,/;
          push @{ $foos_by_cat{$cat} }, $foo;
       }
    }
    
    for my $cat (keys %foos_by_cat) {
       open(my $fh_out, '>', $cat) or die $!;
       for my $foo (@{ $foos_by_cat{$cat} }) {
          print($fh_out "$foo\n");
       }
    }
    

    我写了内部循环,以显示读写之间的对称性,但也可以写成如下:

    print($fh_out "$_\n") for @{ $foos_by_cat{$cat} };
    

    【讨论】:

    • 很高兴看到这两种方法。但是有一个问题,在词法范围内使用第一个循环是否有好处?
    • @jaypal:它避免了对显式 close $fh_in 的需要,因为当 $fh_in 超出范围时文件句柄会隐式关闭。在我自己的回答中,我刚刚将其打开,以便 Perl 在程序终止时关闭。
    • 感谢@Borodin,这是有道理的。
    • @jaypal,代码结构。将输入逻辑与输出逻辑分开。输出代码没有理由访问输入代码使用的变量。
    • 大多数程序都比较复杂,并且会使用实际的子程序。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-12
    • 2017-02-24
    • 1970-01-01
    • 2013-02-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多