逐行阅读不起作用

时间:2014-04-19 21:54:44

标签: perl hash while-loop split

我有一个像这样的文件

key1 value1
key2 value2
key3 value3

我想通过分割空白处的每一行来创建一个哈希。我试过这样的

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

这给出了输出

key1 => value1, key2

并忽略其余行。

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

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

为什么会这样做?

2 个答案:

答案 0 :(得分: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" }

<强>更新

如果您确实想要在一行中执行此操作(尽管我建议您不这样做),您只需在代码中将exists替换为defined ,给予

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

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

但是请使用简单的if语句,以便自动生命的变幻莫测,不会让那些必须维护代码的人感到复杂


<强>更新

这是另一种方式

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

这个和标准if都正常工作,因为在评估.=运算符之前测试了条件。仅当指定的值使用条件表达式时才首先执行.=

答案 1 :(得分:0)

这是另一种方式

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