我有一个哈希,我在其中存储客户购买的产品(%orders
)。它使用产品代码作为键,并引用一个数组,其他信息作为值。
在程序结束时,我必须将库存重写为更新版本(即减去购买商品的数量)
这就是我重写库存的方式:
sub rewriteInventory{
open(FILE,'>inv.txt');
foreach $key(%inventory){
print FILE "$key\|$inventory{$key}[0]\|$inventory{$key}[1]\|$inventory{$key}[2]\n"
}
close(FILE);
}
其中$inventory{$key}[x]
为0
→Title
,1
→price
,2
→quantity
。
这里的问题是,当我看到inv.txt
之后,我会看到这样的事情:
CD-911|Lady Gaga - The Fame|15.99|21
ARRAY(0x145030c)|||
BOOK-1453|The Da Vinci Code - Dan Brown|14.75|12
ARRAY(0x145bee4)|||
这些ARRAY(0x145030c)|||
条目来自哪里?或者更重要的是,我该如何摆脱它们呢?
答案 0 :(得分:4)
你想迭代
keys %inventory
而不是
%inventory
,如您所见,使您迭代键值对。
答案 1 :(得分:3)
您在列表上下文中使用了哈希,因此您可以使用密钥获取所有值。我想你真正想做的是:
foreach $key (keys %inventory) {
print FILE "...";
}
答案 2 :(得分:2)
join
,则无需实际使用$inventory{$key}->[0]
,但实际上可以使用最初发布的$inventory{$key}[0]
。
请注意,第一个(哈希)括号不表示取消引用,但第二个(数组)括号表示。输出中的错误数组引用不仅来自循环键,还来自循环的值。
原始回答:
除了使用keys
之外,您还需要取消引用数组引用(这就是为什么您看到每个值输出为带有地址的ARRAY ---您正在打印引用,当你打印时,不是取消引用数组的值),所以你的循环就像:
foreach my $key (sort keys %inventory) {
print FILE "$key\|$inventory{$key}->[0]\|$inventory{$key}->[1]\|$inventory{$key}->[2]\n";
}
我可能会更加惯用地重写它:
foreach my $key (sort keys %inventory) {
print FILE (join '|', $key, @{$inventory{$key}}) . "\n";
}
希望有所帮助!
答案 3 :(得分:2)
这是编写该例程的一种方法:
#!/usr/bin/perl
use strict; use warnings;
my %inventory;
while ( my $line = <DATA> ) {
chomp $line;
my ($key, @values) = split qr{\|}, $line;
last unless @values;
$inventory{$key} = \@values;
}
write_inventory(\%inventory, 'test.txt');
sub write_inventory {
my ($inventory, $output_file) = @_;
open my $output, '>', $output_file
or die "Cannot open '$output_file': $!";
for my $item ( keys %$inventory ) {
unless ( 'ARRAY' eq ref $inventory{$item} ) {
warn "Invalid item '$item' in inventory\n";
next;
}
print $output join('|', $item, @{ $inventory{$item} }), "\n";
}
close $output
or die "Cannot close '$output': $!";
}
__DATA__
CD-911|Lady Gaga - The Fame|15.99|21
BOOK-1453|The Da Vinci Code - Dan Brown|14.75|12