【问题标题】:Isolating hash values with same key inside an array, inside of an anonymous hash在匿名散列内部的数组中使用相同的键隔离散列值
【发布时间】:2021-06-23 21:55:36
【问题描述】:

我正在开展一个向我们介绍匿名哈希的项目。作业要求我们使用匿名哈希作为基础对象,然后添加键值“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 "!"; 

【问题讨论】:

    标签: arrays perl data-structures anonymous-types


    【解决方案1】:

    您想要格式化多个项目列表,所以让我们创建一个子例程。

    sub format_list {
       return "nothing" if @_ == 0;
       return $_[0] if @_ == 1;
       # ...
    }
    
    say "My ideal pizza has ", format_list( @{ $hash{pizza_toppings} } ), ".";
    

    上面处理了两种边缘情况:当列表为空时,以及当它只有一项时。

    那么缺少的部分是什么?嗯,你想要

    XXX, XXX, ... XXX, and XXX
    

    有两种看待这个的方式。

    方法 A

    XXX, XXX, ... XXX, and XXX
    \_______________/\____/\_/
                    \     \  \__ Last item
                     \     \____ Glue
                      \_________ A list of items separated by ", "
    

    join 是一个显而易见的选择。

    return join(", ", @_[ 0 .. $#_ - 1 ]) . ", and " . $_[-1];
    

    @_是参数数组,
    @_[...]@_返回标识的元素,
    $#_是数组@_的最后一个索引,
    $_[-1]是最后一个参数。

    方法 B

    XXX, XXX, ... 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';

    • $g {'genre'} 中的空格真的很奇怪。

    • 在哈希索引表达式中,当字符串是标识符(有效的 var 名称,如 genre)时,您可以删除字符串文字的引号。

    • my %g = (%{$i}); ... $g{'genre'} 不必要地创建了整个哈希的副本。 $i->{genre} 会更好。

    【讨论】:

    • 太棒了,非常感谢!绝对超出我的认知!我已经有了一个工作的浇头,但我不知道如何结合它以及我必须访问的流派和标题,这是另一层。我无法取消引用它们。我在下面做了这个,但我得到“我喜欢看 HASH(0x2b06a08)、HASH(0x2b06b40) 和 HASH(0x2b06f30) 电影”,因为我仍然只看电影。 /sub format_list { 如果@_ == 0,则返回“无”;如果@_ == 1,则返回 $_[0];返回 join(", ", @_[ 0 .. $#_ - 1 ]) 。 “, 和 ” 。 $_[-1]; } 说“我喜欢看”、format_list(@{ $hash{movies} })、“电影”;
    • 将每个 ref 替换为其 genre 元素的值:format_list( map { $_->{genre} } @{ $hash{movies} } )
    • 你是我的英雄!非常感谢!
    猜你喜欢
    • 2014-01-08
    • 1970-01-01
    • 2012-07-20
    • 2015-02-03
    • 2018-07-27
    • 1970-01-01
    • 2017-02-09
    • 2014-05-19
    • 1970-01-01
    相关资源
    最近更新 更多