【问题标题】:Perl : Reading a hash with split line element as a keyPerl:以分割线元素为键读取哈希
【发布时间】:2021-11-09 10:49:25
【问题描述】:

我试图通过引用散列来操作文件,但很难将密钥传递给散列。

输入文件是一个简单的 CSV,

    ATFTP1-a, brah, brah2,
    ATFTP1-J, brah, brah2,
    ATFTP1-m, brah, brah2,

我想在第二列中插入一个元素。该元素应该是哈希中的一个值,它与第一个元素作为键匹配。

my %Ctct2Bob = (
    "ATFTP1-a" => "24" ,
    "ATFTP1-b" => "25" ,
    "ATFTP1-j" => "100" ,
    "ATFTP1-m" => "33" ,
)

while( my $line = <IN> ){
    my @linestuff = split(',',$line);
        print "@linestuff[0],";
        my $key = $linestuff[0];
        print $Ctct2Bob{$key};

        ...
        print "\n";
}

我想要的是

    ATFTP1-a,24, brah, brah2,
    ATFTP1-J,100, brah, brah2,
    ATFTP1-m,33, brah, brah2,

对于我的一生,我无法打印价值。不过,我可以打印元素 $Ctct2Bob{'ATFTP1-a'}。

【问题讨论】:

    标签: arrays file perl hash


    【解决方案1】:

    您可以使用splice 插入到列表的中间:

    #!/usr/bin/env perl
    use strict;
    use warnings;
    use feature qw/say/;
    
    my %Ctct2Bob = (
        "ATFTP1-a" => "24" ,
        "ATFTP1-b" => "25" ,
        "ATFTP1-j" => "100" ,
        "ATFTP1-m" => "33" ,
        );
    
    while (my $line = <DATA>){
        chomp $line;
    
        # Need the -1 here to preserve the empty trailing field
        my @linestuff = split /\s*,\s*/, $line, -1;
    
        # If the first array element exists in the hash, insert its
        # value as the new second element, else a default value. 
        if (exists $Ctct2Bob{$linestuff[0]}) {
            # Insert before the current second element (Offset 1).
            splice @linestuff, 1, 0, $Ctct2Bob{$linestuff[0]};
        } else {
            splice @linestuff, 1, 0, "Not found";
        }
    
        # And print the line out.
        say join(",", @linestuff);
    }
    
    __DATA__
    ATFTP1-a, brah, brah2,
    ATFTP1-J, brah, brah2,
    ATFTP1-m, brah, brah2,
    

    注意:我建议切换到 Text::CSV_XS 来处理在任何严重的 perl 程序中读取 CSV 数据,但对于像您的示例这样的简单数据,逗号上的 split 可以提供服务。

    【讨论】:

      【解决方案2】:

      一个简单的split 和数组的re-shuffle 就可以解决问题。

      注意:假设 %Ctct2Bob 中的哈希值而不是 "ATFTP1-j" =&gt; "100" , 应该是 "ATFTP1-J" =&gt; "100" , -- 基于所需的输出

      use strict;
      use warnings;
      use feature 'say';
      
      my %Ctct2Bob = (
          "ATFTP1-a" => "24" ,
          "ATFTP1-b" => "25" ,
          "ATFTP1-J" => "100" ,
          "ATFTP1-m" => "33" ,
      );
      
      while( <DATA> ){
          chomp;
          my($key,@data) = split ',';
          @data = $Ctct2Bob{$key} ? ($key,$Ctct2Bob{$key},@data) : ($key,@data);
          say join(',',@data);
      }
      
      exit 0;
      
      __DATA__
      ATFTP1-a, brah, brah2,
      ATFTP1-J, brah, brah2,
      ATFTP1-m, brah, brah2,
      

      输出

      ATFTP1-a,24, brah, brah2
      ATFTP1-J,100, brah, brah2
      ATFTP1-m,33, brah, brah2
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-07-19
        • 2012-04-28
        • 1970-01-01
        • 2012-12-11
        • 2016-01-28
        • 2014-07-13
        • 1970-01-01
        • 2011-10-27
        相关资源
        最近更新 更多