问题描述
我正在做一个向我们介绍匿名哈希的项目。赋值要求我们使用匿名哈希作为基础对象,然后添加键值 'pizza_toppings',一个至少包含 5 个元素的数组;和 'movies',一个包含至少 3 个哈希对象的数组,其键必须是 'title' 和 'genre'。还有一点关于修改比萨,我已经实现了。
我遇到的问题是,当具有相同的密钥时,我不确定如何访问单个哈希值。我的目标是清理输出,因此我需要能够在最后一个条目之前切断循环,添加“and”,然后打印最后一个,使其看起来像这样:
我理想的披萨有菠萝、蘑菇、洋葱、番茄、奶酪和青椒。
我喜欢看科幻、动作和奇幻电影。
我最喜欢的是《降临》、《地下六人》和《实用魔法》!
这是我目前所拥有的。它可以工作,但只是格式不正确。我也有兴趣听到比我所做的更好的打印流派和标题的解决方案。我还是个小写手!我们没有真正得到任何解释,我也无法找到如何访问这样几个级别的内容。
use 5.26.1;
use strict;
use warnings;
my %hash = (
'pizza_toppings' => ['pineapple','mushroom','onion','tomato','cheese'],'movies' => [
{'genre' => 'SciFi','title' => 'Arrival'},{'genre' => 'Action','title' => 'Six Underground'},{'genre' => 'Fantasy','title' => 'Practical Magic'}
]
);
#adding 'green peppers' to the list of toppings
my $rf = $hash{pizza_toppings};
$rf -> [5] = 'green peppers';
print "My ideal pizza has ";
#Printing out the list of toppings
foreach my $i ( @{ $hash{pizza_toppings} } ) {
print $i . ",";
};
print ".\nI like to watch ";
#printing out the list of genres
foreach my $i ( @{ $hash{movies} } ) {
my %g = (%{$i});
print $g {'genre'} . ",";
};
say " movies.";
print "Some of my favourites are ";
#printing out the list of titles
foreach my $j ( @{ $hash{movies} } ) {
my %t = (%{$j});
print $t {'title'} . ",";
};
say "!";
解决方法
您想要格式化多个项目列表,所以让我们创建一个子例程。
mmap
上面处理了两种边缘情况:当列表为空时,当它只有一项时。
那么缺少的部分是什么?好吧,你想要
sub format_list {
return "nothing" if @_ == 0;
return $_[0] if @_ == 1;
# ...
}
say "My ideal pizza has ",format_list( @{ $hash{pizza_toppings} } ),".";
有两种看待这个的方式。
方法 A
XXX,XXX,... XXX,and XXX
XXX,and XXX
\_______________/\____/\_/
\ \ \__ Last item
\ \____ Glue
\_________ A list of items separated by ","
在这里是一个明显的选择。
join
return join(",",@_[ 0 .. $#_ - 1 ]) . ",and " . $_[-1];
是参数数组,@_
从 @_[...]
,
返回标识的元素
@_
是数组 $#_
的最后一个索引,@_
是最后一个参数。
方法 B
$_[-1]
XXX,and XXX
\_________________/\__/\_/
\ \ \__ Last item
\ \____ Glue
\_______ A list of items all ending with ","
或
my $s = "";
for my $i ( 0 .. $#_ - 1 ) {
$s .= $_ . ",";
}
return $s . "and " . $_[-1];
提示:
-
return join("",map { "$_," } @_[ 0 .. $#_ - 1 ]) . "and " . $_[-1];
最好写成$rf -> [5] = 'green peppers';
或push @{ $rf },'green peppers';
-
push $rf->@*,'green peppers';
中的空格真的很奇怪。 -
在哈希索引表达式中,当字符串是标识符(有效的 var 名称,如
$g {'genre'}
)时,您可以删除字符串文字的引号。 -
genre
不必要地创建了整个散列的副本。my %g = (%{$i}); ... $g{'genre'}
会更好。