Perl:使用循环创建哈希文件
Perl: Create a hash file using a loop
我从 XML 文件中导入数据,并希望将内容输出到日志文件中。为此,我为每个实体创建了一个标量 (2)。为了使用循环输出实体,我创建了一个散列(3 和 4b),并使用 for 循环输出标签(实体)的名称和值 (5)。要获得指定的顺序,我使用 Tie::IxHash
。现在,我想知道是否可以使用 for 循环来避免步骤 (3) 和 (4b)。例如,我可以将标量 $x1
、$x2
和 $x3
放入一个数组中,然后循环执行步骤 (3) 和 (4b)。可能吗?
use strict;
use warnings;
use Data::Dumper;
use Tie::IxHash;
my $x1 = 'a';
my $x2 = '';
my $x3 = undef; # no xml tag <x3>;
# (3) Create a hash to output values in a log files using for
my $rx1 = $x1;
my $rx2 = $x2;
my $rx3 = $x3;
# (4a) To make an ordered hash use Tie::IxHash
my %h;
tie %h, 'Tie::IxHash';
%h = ( 'x1' => $rx1
, 'x2' => $rx2
, 'x3' => $rx3);
# (4c) Output hash with undex content gives a warning
print map { "$_ ${$h{$_}}\n" } keys %h; # 51
# Use of uninitialized value in concatenation (.) or string at test.pl line 51.
print "--------\n";
# (5) Output content of hash into a log file
print "using keys from hash:\n";
foreach my $k (keys %h) {
if ( not defined ${$h{$k}} or ${$h{$k}} eq "" ) {${ $h{$k}} = undef; }
if ( defined ${$h{$k}} ) { print "$k : ${$h{$k}} \n"; } else {print "$k : undef\n"; }
}
这给出了输出:
# Output:
# Use of uninitialized value in concatenation (.) or string at test.pl line 51.
# x1 a
# x2
# x3
# --------
# using keys from hash:
# x1 : a
# x2 : undef
# x3 : undef
更新 1:
多亏了 Dave Cross,我想到了这个。它对我有用。
# Define hash [(step (1)-(4)]
%h = ( 'x1' => my $x1
, 'x2' => my $x2
, 'x3' => my $x3
);
# import from xml
$h{x1} = 'a';
$h{x2} = '';
$h{x3} = undef;
# (5) Output content of hash into a log file
print "using keys from hash:\n";
foreach my $k (keys %h) {
if ( not defined $h{$k} or $h{$k} eq "" ) { $h{$k} = undef; }
if ( defined $h{$k} ) { print "$k : $h{$k} \n"; } else {print "$k : undef\n"; }
}
更新 2
感谢 choroba 和 Dave Cross 的建议,我进行了简化。现在它简短而有条理。我了解到您可以将接口中的数据直接分配给散列或数组中的标量。通常我喜欢单独声明标量变量,但在这种情况下,如果你有无数的变量,只将它写入散列或数组一次并单独声明散列或数组是有意义的。
# Define hash [(step (1)-(4)]
%h = ( x1 => $xpc->findvalue('./X1',$node1)
, x2 => $xpc->findvalue('./X2',$node1)
, x3 => $xpc->findvalue('./X3',$node1)
);
# (5) Output content of hash into a log file
print "using keys from hash:\n";
for my $k (keys %h) {
if ( not defined $h{$k} or $h{$k} eq "" ) { $h{$k} = undef; }
if ( defined $h{$k} ) { print "$k : $h{$k} \n"; } else {print "$k : undef\n"; }
}
您的 foreach
循环可以更简单一些。
# To enable 'say()' - this is usually at the top of the file
use feature 'say';
for my $k (keys %h) {
$h{$k} = undef if defined $h{$k} and $h{$k} eq '';
say "$k : ", $h{$k} // 'undef';
}
- 如果您要将其设置为
undef
,请不要检查 undef
- 使用后缀条件使代码更易于阅读
- 在打印语句中使用了
//
(defined-or) 运算符
- 使用
say()
代替print()
我从 XML 文件中导入数据,并希望将内容输出到日志文件中。为此,我为每个实体创建了一个标量 (2)。为了使用循环输出实体,我创建了一个散列(3 和 4b),并使用 for 循环输出标签(实体)的名称和值 (5)。要获得指定的顺序,我使用 Tie::IxHash
。现在,我想知道是否可以使用 for 循环来避免步骤 (3) 和 (4b)。例如,我可以将标量 $x1
、$x2
和 $x3
放入一个数组中,然后循环执行步骤 (3) 和 (4b)。可能吗?
use strict;
use warnings;
use Data::Dumper;
use Tie::IxHash;
my $x1 = 'a';
my $x2 = '';
my $x3 = undef; # no xml tag <x3>;
# (3) Create a hash to output values in a log files using for
my $rx1 = $x1;
my $rx2 = $x2;
my $rx3 = $x3;
# (4a) To make an ordered hash use Tie::IxHash
my %h;
tie %h, 'Tie::IxHash';
%h = ( 'x1' => $rx1
, 'x2' => $rx2
, 'x3' => $rx3);
# (4c) Output hash with undex content gives a warning
print map { "$_ ${$h{$_}}\n" } keys %h; # 51
# Use of uninitialized value in concatenation (.) or string at test.pl line 51.
print "--------\n";
# (5) Output content of hash into a log file
print "using keys from hash:\n";
foreach my $k (keys %h) {
if ( not defined ${$h{$k}} or ${$h{$k}} eq "" ) {${ $h{$k}} = undef; }
if ( defined ${$h{$k}} ) { print "$k : ${$h{$k}} \n"; } else {print "$k : undef\n"; }
}
这给出了输出:
# Output:
# Use of uninitialized value in concatenation (.) or string at test.pl line 51.
# x1 a
# x2
# x3
# --------
# using keys from hash:
# x1 : a
# x2 : undef
# x3 : undef
更新 1:
多亏了 Dave Cross,我想到了这个。它对我有用。
# Define hash [(step (1)-(4)]
%h = ( 'x1' => my $x1
, 'x2' => my $x2
, 'x3' => my $x3
);
# import from xml
$h{x1} = 'a';
$h{x2} = '';
$h{x3} = undef;
# (5) Output content of hash into a log file
print "using keys from hash:\n";
foreach my $k (keys %h) {
if ( not defined $h{$k} or $h{$k} eq "" ) { $h{$k} = undef; }
if ( defined $h{$k} ) { print "$k : $h{$k} \n"; } else {print "$k : undef\n"; }
}
更新 2
感谢 choroba 和 Dave Cross 的建议,我进行了简化。现在它简短而有条理。我了解到您可以将接口中的数据直接分配给散列或数组中的标量。通常我喜欢单独声明标量变量,但在这种情况下,如果你有无数的变量,只将它写入散列或数组一次并单独声明散列或数组是有意义的。
# Define hash [(step (1)-(4)]
%h = ( x1 => $xpc->findvalue('./X1',$node1)
, x2 => $xpc->findvalue('./X2',$node1)
, x3 => $xpc->findvalue('./X3',$node1)
);
# (5) Output content of hash into a log file
print "using keys from hash:\n";
for my $k (keys %h) {
if ( not defined $h{$k} or $h{$k} eq "" ) { $h{$k} = undef; }
if ( defined $h{$k} ) { print "$k : $h{$k} \n"; } else {print "$k : undef\n"; }
}
您的 foreach
循环可以更简单一些。
# To enable 'say()' - this is usually at the top of the file
use feature 'say';
for my $k (keys %h) {
$h{$k} = undef if defined $h{$k} and $h{$k} eq '';
say "$k : ", $h{$k} // 'undef';
}
- 如果您要将其设置为
undef
,请不要检查 - 使用后缀条件使代码更易于阅读
- 在打印语句中使用了
//
(defined-or) 运算符 - 使用
say()
代替print()
undef