我在编写Perl脚本时遇到了麻烦。
这是任务:
我的代码工作正常,但有两个问题。
我想在哈希%grocery
中添加一个元素,其中包含类别,品牌和价格。添加项目时,首先系统会询问类别。
如果该类别不存在,那么它将从用户添加新类别,品牌和价格,但如果该类别已存在,则它将从用户获取品牌名称和价格并将其附加到现有类别。
当我尝试这样做时,它会删除先前存在的项目。我希望先前的项目附加了新添加的项目。
此问题与最大值有关。查找给定哈希值的最大价格。我正在为此获得垃圾价值。
我做错了什么?
这是我的完整代码:
use strict;
use warnings;
use List::Util qw(max);
use feature "switch";
my $b;
my $c;
my $p;
my $highest;
print "____________________________STORE THE ITEM_____________________\n";
my %grocery = (
"soap" => { "lux" => 13.00, "enriche" => 11.00 },
"detergent" => { "surf" => 18.00 },
"cleaner" => { "domex" => 75.00 }
);
foreach my $c ( keys %grocery ) {
print "\n";
print "$c\n";
foreach my $b ( keys %{ $grocery{$c} } ) {
print "$b:$grocery{$c}{$b}\n";
}
}
my $ch;
do {
print "________________MENU_________________\n";
print "1.ADD ITEM\n";
print "2.SEARCH\n";
print "3.DISPLAY\n";
print "4.FIND THE MAX PRICE\n";
print "5.EXIT\n";
print "enter your choice \n";
$ch = <STDIN>;
chomp( $ch );
given ( $ch ) {
when ( 1 ) {
print "Enter the category you want to add";
$c = <STDIN>;
chomp( $c );
if ( exists( $grocery{$c} ) ) {
print "Enter brand\n";
$b = <STDIN>;
chomp( $b );
print "Enter price\n";
$p = <STDIN>;
chomp( $p );
$grocery{$c} = { $b, $p };
print "\n";
}
else {
print "Enter brand\n";
$b = <STDIN>;
chomp( $b );
print "Enter price\n";
$p = <STDIN>;
chomp( $p );
$grocery{$c} = { $b, $p };
print "\n";
}
}
when ( 2 ) {
print "Enter the item that you want to search\n";
$c = <STDIN>;
chomp( $c );
if ( exists( $grocery{$c} ) ) {
print "category $c exists\n\n";
print "Enter brand\n";
$b = <STDIN>;
chomp( $b );
if ( exists( $grocery{$c}{$b} ) ) {
print "brand $b of category $c exists\n\n";
print "-----$c-----\n";
print "$b: $grocery{$c}{$b}\n";
}
else {
print "brand $b does not exists\n";
}
}
else {
print "category $c does not exists\n";
}
}
when ( 3 ) {
foreach $c ( keys %grocery ) {
print "$c:\n";
foreach $b ( keys %{ $grocery{$c} } ) {
print "$b:$grocery{$c}{$b}\n";
}
}
}
when ( 4 ) {
print "\n________________PRINT HIGHEST PRICED PRODUCT____________________\n";
$highest = max values %grocery;
print "$highest\n";
}
}
} while ( $ch != 5 );
答案 0 :(得分:4)
当我尝试这样做时,它会删除先前存在的项目。我希望先前的项目附加新添加的项目。
在此行中,您将使用新的哈希引用覆盖$grocery{$c}
的值。
$grocery{$c}={$b,$p};
相反,您需要编辑现有的哈希引用。
$grocery{$c}->{$b} = $p;
这将为$b
内的现有数据结构添加新密钥$grocery{$b}
,并为其指定$p
的值。
让我们来看看这意味着什么。我在%grocery
初始化后将其添加到代码中。
use Data::Dumper;
print Dumper \%grocery;
我们将获得以下输出。哈希值未排序,因此您的订单可能会有所不同。
$VAR1 = {
'cleaner' => {
'domex' => '75'
},
'detergent' => {
'surf' => '18'
},
'soap' => {
'enriche' => '11',
'lux' => '13'
}
};
正如你所看到的,我们在哈希中有哈希。在Perl中,引用用于构造多级数据结构。您可以从输出中的花括号{}
中看到它。 $VAR1
之后的第一个是因为我通过在前面添加反斜杠$grocery
将Dumper
的引用传递给\
。
因此,$grocery{"cleaner"}
的值后面是哈希引用{ "domex" => 75 }
。要进入该哈希引用,您需要使用解除引用运算符->
。然后,您可以将新密钥放入该哈希引用中,如上所示。
# ##!!!!!!!!!!
$grocery{"cleaner"}->{"foobar"} = 30;
我已通过评论标记了上述相关部分。您可以在以下文档中阅读这些内容:perlreftut,perllol,perldsc和perlref。
此问题与最大值有关。查找给定哈希值的最大值。我正在为此获得垃圾价值。
这个问题也是基于你还没有理解参考文献的事实。
$highest = max values %grocery;
您的代码只会直接在%grocery
中获取值。如果向上滚动并再次查看Dumper输出,您将看到%grocery
内有三个哈希引用。现在,如果你不取消引用它们,你只需要获得它们的标量表示。 Perl中的标量是单个值,如数字或字符串。但是对于参考,它是他们的类型和地址。看起来像垃圾的事实上是%grocery
中具有最高数量的三个哈希引用的内存地址。
当然,这不是你想要的。您需要迭代数据结构的两个级别,收集所有值,然后找到最高值。
my @all_prices;
foreach my $category (keys %grocery) {
push @all_prices, values %{ $grocery{$category} };
}
$highest = max @all_prices;
print "$highest\n";
我选择了一种非常冗长的方法来做到这一点。它迭代%grocery
中的所有类别,然后抓取存储在每个类别后面的哈希引用的所有values
。那些被添加到数组中,最后我们可以从数组中获取所有这些max
。
答案 1 :(得分:2)
对于类别已存在且何时不存在,您具有完全相同的代码。这条线
August 28, 2016 at 09:20AM = 2
August 28, 2016 at 09:26AM = 3
替换类别$grocery{$c} = { $b, $p };
的整个哈希值。这对于新类别来说很好,但是如果该类别已经存在,那么它将丢弃任何现有信息
你需要写
$c
请在运算符周围添加更多空格,分隔列表元素,并描述相关的语句序列
关于找到最高价格,您的行
$grocery{$c}{$b} = $p;
正在尝试计算与类别
对应的哈希引用的最大值由于此处有两个哈希级别,您需要
$highest = max values %grocery;
但这可能不是您期望的方式。如果有疑问,那么你应该使用两个嵌套的$highest = max map { values %$_ } values %grocery;
循环
答案 2 :(得分:-3)
use List::Util qw(max);
use Data::Dumper;
my $grocery =
{
"soap" => { "lux" => 13.00, "enriche" => 11.00 },
"detergent" => { "surf" => 18.00 },
"cleaner" => { "domex"=> 75.00 }
};
display("unadulterated list");
print Dumper $grocery;
display("new silky soap");
$grocery->{"soap"}->{"silky"} = 12.50;
print Dumper $grocery;
display("new mega cleaner");
$grocery->{"cleaner"}->{"megaclean"} = 99.99;
print Dumper $grocery;
display("new exfoliant soap");
$grocery->{"soap"}->{"exfoliant"} = 23.75;
print Dumper $grocery;
display("lux soap gets discounted");
$grocery->{"soap"}->{"lux"} = 9.00;
print Dumper $grocery;
display("domex cleaner is discontinued");
delete $grocery->{"cleaner"}->{"domex"};
print Dumper $grocery;
display("most costly soap product");
my $max = max values $grocery->{soap};
print $max, "\n\n";
sub display
{
printf("\n%s\n%s\n%s\n\n", '-' x 45, shift, '-' x 45 );
}