syk*_*ker 9 arrays perl hash reference
在Perl中执行这些行之后:
my $data = `curl '$url'`;
my $pets = XMLin($data)->(pets);
Run Code Online (Sandbox Code Playgroud)
我有一个包含对哈希的引用的数组引用:
$VAR1 = [
{
'title' => 'cat',
'count' => '210'
},
{
'title' => 'dog',
'count' => '210'
}
]
Run Code Online (Sandbox Code Playgroud)
在Perl中,我如何首先按照计数对哈希进行排序,然后按标题对哈希进行排序.然后打印到STDOUT计数,然后打印每个换行符上的标题.
假设您希望按降序排列计数并且标题升序:
print map join(" ", @$_{qw/ count title /}) . "\n",
sort { $b->{count} <=> $a->{count}
||
$a->{title} cmp $b->{title} }
@$pets;
Run Code Online (Sandbox Code Playgroud)
这是以功能风格编写的紧凑代码.为了帮助理解它,让我们以更熟悉,命令式的方式查看等效代码.
Perl的sort运算符采用可选的SUBNAME参数,该参数允许您将比较分解出来,并为其指定一个描述其功能的名称.当我这样做时,我喜欢开始使用sub的名字,by_以便sort by_...更自然地做好准备.
首先,你可能已经写过了
sub by_count_then_title {
$b->{count} <=> $a->{count}
||
$a->{title} cmp $b->{title}
}
my @sorted = sort by_count_then_title @$pets;
Run Code Online (Sandbox Code Playgroud)
请注意,此表单中的SUBNAME后面没有逗号!
为了解决另一个评论者的问题,你可以使用or,而不是||在by_count_then_title,如果你觉得它更具可读性.双方<=>并cmp 具有更高的优先级比(你想象中的更紧密结合)||和or,所以它是严格的风格问题.
要打印排序的数组,可能会有更熟悉的选择
foreach my $p (@sorted) {
print "$p->{count} $p->{title}\n";
}
Run Code Online (Sandbox Code Playgroud)
$_如果您没有指定获取每个值的变量,Perl会使用,因此以下内容具有相同的含义:
for (@sorted) {
print "$_->{count} $_->{title}\n";
}
Run Code Online (Sandbox Code Playgroud)
在for和foreach关键字是同义词,但我发现,上面的用途,即,foreach如果我要去命名变量或for否则,读最自然的.
使用map,近亲foreach,但没有太大的不同:
map print("$_->{count} $_->{title}\n"), @sorted;
Run Code Online (Sandbox Code Playgroud)
你也可以print通过以下方式宣传map:
print map "$_->{count} $_->{title}\n",
@sorted;
Run Code Online (Sandbox Code Playgroud)
最后,为了避免重复$_->{...},散列片 @$_{"count", "title"}给出了与循环当前记录中的count和title相关的值.拥有这些值后,我们需要将它们与一个空格连接起来,并为结果添加换行符,所以
print map join(" ", @$_{qw/ count title /}) . "\n",
@sorted;
Run Code Online (Sandbox Code Playgroud)
请记住,这qw//是编写字符串列表的简写.如此示例所示,map从前向后(或从我缩进的方式从下到上)读取表达式:首先对记录进行排序,然后对其进行格式化,然后打印它们.
您可以消除临时@sorted但调用命名比较:
print map join(" ", @$_{qw/ count title /}) . "\n",
sort by_count_then_title
@$pets;
Run Code Online (Sandbox Code Playgroud)
如果应用程序join对您的口味过于冗长,那么
print map "@$_{qw/ count title /}\n",
sort by_count_then_title
@$pets;
Run Code Online (Sandbox Code Playgroud)