【问题标题】:changing a hash value from string to array将哈希值从字符串更改为数组
【发布时间】:2013-06-05 13:01:23
【问题描述】:

数据.txt

 Name:xyz
 ID:1
 Value: 1 2 3 4 5 6 7 8 9 ...
 ID:2 
 Value: 9 8 7 6 5 4 3 2 1..
 ID:3
 Value: 90 89 88....
 Name:abc
 ID:11
 value:...

初始文件.txt

## Header 
..
data
data
data
..

最终预期的文件.txt

## Header xyz_1,xyz_2,xyz_3,abc_11,...
..
data 1 9 90
data 2 8 89
data 3 7 88
data 4 6 
..

当前输出文件.txt

## Header xyz_1,xyz_2,xyz_3,abc_11,...
...
data, 1 2 3 4 5 6 7 8 9 ..,9 8 7 6 5 4 3 2 1 ..,90 89 88
data
data
...

代码

#!/usr/local/bin/perl
use diagnostics;
use strict;
use warnings;

use Tie::File;

my @name_id;
my %test;

#local $/ = '';

open my $fh, '<', 'data.txt' or die "failed: $!";
my %var;
while (<$fh>) {
  chomp;
  if (m/^([A-Z:]+):\s*(.*)/) {
    $var{$1} = $2;
    if (exists($var{Name}) && exists($var{ID}) && exists($var{value}) && $1 eq 'value') {
      my $var_name = "$var{Name}_$var{ID}";
      push @name_id, $var_name;
      $test{$var_name} = $var{value};
    }
  }
}

#   print join "\n\t", @test{@name_id};
my $match = "## Header";
tie my @lines, 'Tie::File', 'file.txt' or die "failed : $!";
for my $line (@lines) {
  if ($line =~ /^($match.*)/) {
    $line = $1 . "," . join ',', @name_id;
  }
}
untie @lines;

my $match = "data";
tie my @lines, 'Tie::File', 'file.txt' or die "failed : $!";
my $i = 0;
for my $line (@lines) {
  if ($line =~ /^($match.*)/) {
    $line = $1 . "," . join(',', map { $test{$_}->[$i] } @name_id);
    $i++;
  }
}
untie @lines;

这行有问题$line = $1 . "," . join (',', map { $test{$_}-&gt;[$i]} @name_id); 它会抛出错误

不能使用字符串 ("1 2 3 4 5 6 7 8 9 .."...) 作为数组引用,而在 test.pl 第 46 行、第 80 行使用“严格引用”。在测试中。第 46 行

我认为我拥有的 hash(%test) 值是一个字符串,我不能将它拆分为一个数组。请让我知道如何将其转换为数组。我试过 $test{$var_name} = [qw($var{value})]; 没用。

【问题讨论】:

  • 为什么要将$i$1 混合在同一个代码中?为什么:(。请重命名。

标签: perl


【解决方案1】:

您可能对您的代码重构感兴趣,该重构似乎可以满足您的需求。

#!/usr/local/bin/perl
use strict;
use warnings;

use Tie::File;

open my $fh, '<', 'data.txt' or die "failed: $!";

my @name_id;
my %test;
my %var;

while (<$fh>) {
  chomp;
  if (my ($key, $val) = /^(\w+):\s*(.*)/) {
    $var{$key} = $val;
    if ($key eq 'value') {
      my $var_name = "$var{Name}_$var{ID}";
      push @name_id, $var_name;
      $test{$var_name} = [ split ' ', $var{value} ];
    }
  }
}

tie my @lines, 'Tie::File', 'file.txt' or die "failed : $!";
my $count = 0;
for my $line (@lines) {
  if ($line =~ /^## Header/) {
    $line .= ' ' . join ',', @name_id;
  }
  elsif ($line =~ /^data/) {
    $line .= ' ' . join ' ', map { $test{$_}[$count] // '' } @name_id;
    $count++;
  }
}
untie @lines;

输出 (file.txt)

## Header xyz_1,xyz_2 ,xyz_3
data 1 9 90
data 2 8 89
data 3 7 88
data 4 6 

【讨论】:

    【解决方案2】:

    这肯定不对:

    $test{$_}->[$i]
    

    因为$test{$_} 只能包含某种字符串。

    如果你有一个字符串并且想要拆分成一个数组引用,那么上面的方法就可以了,这样做:

    $test{$var_name} = [split /\s+/, $var{value}];
    

    我不知道代码应该完成什么,这意味着它可以运行,但我不知道它是否达到了预期的目的。奇怪的变量名称(如 $test$var_name 并没有帮助我理解其目的)。

    【讨论】:

    • 成功了。这就是我所需要的,尽管它抱怨 ` $line = $1 。 “,”。 join (',', map { $test{$_}->[$i]} @name_id);` 在 test4.pl 第 47 行, 第 141 行 (#1 )
    • 也许您可以使用新代码重新提出新问题。顺便说一句,我仍然认为你应该清理变量名。
    【解决方案3】:

    我不太确定我是否遵循了您的代码,但我想我会发布如何转置数字(除非您的代码已经这样做了:-))。

    #!/usr/bin/perl
    use strict;
    use warnings;
    
    my (%data, $name);
    while (<DATA>) {
        if (/^Name:(.+)/) {
            $name = $1  
        }
        elsif (/^Value/) {
            # transpose
            my $r = 0;
            push @{ $data{$name}[$r++] }, $_ for /\d+/g;
        }   
    }
    
    use Data::Dumper; print Dumper \%data;
    
    __DATA__
    Name:xyz
    ID:1
    Value: 1 2 3 4 5 6 7 8 9
    ID:2 
    Value: 9 8 7 6 5 4 3 2 1
    ID:3
    Value: 90 89 88 87 86 85 84 83 82
    Name:abc
    ID:11
    

    转储的结果是:

    $VAR1 = {
              'xyz' => [
                         [
                           '1',
                           '9',
                           '90'
                         ],
                         [
                           '2',
                           '8',
                           '89'
                         ],
                         [
                           '3',
                           '7',
                           '88'
                         ],
                         [
                           '4',
                           '6',
                           '87'
                         ],
                         [
                           '5',
                           '5',
                           '86'
                         ],
                         [
                           '6',
                           '4',
                           '85'
                         ],
                         [
                           '7',
                           '3',
                           '84'
                         ],
                         [
                           '8',
                           '2',
                           '83'
                         ],
                         [
                           '9',
                           '1',
                           '82'
                         ]
                       ]
            };
    

    【讨论】:

      猜你喜欢
      • 2014-10-29
      • 2017-05-11
      • 2015-09-06
      • 2018-05-26
      • 1970-01-01
      • 1970-01-01
      • 2016-06-12
      • 2021-04-21
      • 1970-01-01
      相关资源
      最近更新 更多