我有一个这样的文件

key1 value1
key2 value2
key3 value3

等等

我想通过在空白处分割每一行来创建一个哈希。 我已经试过了

while (<FILE>) {
  chomp;
  my ($key, $val) = split / /;
  $hash{$key} .= exists $hash{$key} ? ",$val" : $val;
} 

这给出了输出

key1 => value1, key2

其余的行将被忽略。

当我检查逐行读取是否有效时,它没有。

它不会逐行读取,而是while循环仅对所有数据循环一次。

为什么这样做呢?

===============>>#1 票数:2 已采纳

您要在每个哈希值后附加.= ",$val" ,而不管其是否先前存在,因为$hash{$key} .= 隐式创建元素$hash{$key}以便它可以接收分配。 这意味着exists将始终返回true ,并且将仅对条件的第一个分支进行求值。 任何数组或哈希元素都会发生这种情况

您的示例数据是错误的,因为它不包含等号= ,但是我认为您的意思是仅在哈希值已包含数据的情况下才将",$val"附加到哈希值中。 如果没有与$key对应的元素,则只需分配$val

这样也许

use strict;
use warnings;

my %hash;

while (<DATA>) {
  chomp;
  my ($key, $val) = split /=/;
  if ( exists $hash{$key} ) {
    $hash{$key} .= ",$val";
  }
  else {
    $hash{$key} = $val;
  }
} 

use Data::Dump;
dd \%hash;

__DATA__
key1=value1
key2=value2
key3=value3
key1=value4
key2=value5

产量

{ key1 => "value1,value4", key2 => "value2,value5", key3 => "value3" }

更新

如果您确实想单行执行此操作(尽管我不建议这样做),则只需要用代码中defined的代码替换exists的代码,即可

  $hash{$key} .= defined $hash{$key} ? ",$val" : $val;

因为,尽管该元素是自动生存的,所以存在 ,直到收到第一个值,它仍然没有值,因此仍未定义

但是请使用简单的if语句,以免自动执行的变数对那些必须维护您的代码的人来说并不复杂


更新

这是另一种方式

$hash{$key} .= ',' if exists $hash{$key};
$hash{$key} .= $val;

无论这和标准if恰当,因为条件的测试工作.=运营商进行评估。 只有在分配的值使用条件表达式时,才首先执行.=

===============>>#2 票数:0

这是另一种方式

  for my $line(<FILE>){ 
  my ($key, $val) = split(/ /,$line);
  if ( exists $hash{$key} ) {
    $hash{$key} .= "$val";
  }
  else {
    $hash{$key} = $val;
  }

  ask by translate from so

未解决问题?本站智能推荐:

关注微信公众号