perl - 在 Template Toolkit 中按值而不是键对哈希引用进行排序
问题描述
我有一个 perl 多维哈希引用,我以下列方式在 Template Toolkit 中迭代它。有没有办法按 AVG 之类的值之一而不是键对其进行排序?
<tr>
<% FOREACH name in payload_batting.keys.sort %>
<td width="140"><% name.substr(0, 18);%></td>
<td width="55"><% payload_batting.$name.atts %></td>
<td width="55"><% payload_batting.$name.runs %></td>
<td width="55"><% payload_batting.$name.hits %></td>
<td width="55"><% payload_batting.$name.AVG %></td>
<tr>
<% END %>
解决方案
正如池上所说,你必须自己整理。如果您想在表示层中进行排序,在 Template Toolkit 中,您可以在模板本身中作为 Perl 代码进行排序。为此,您必须将 EVAL_PERL 设置为真值。然后代码看起来像这样
[% PERL %]
my $h = $stash->get('payload_batting');
my @k = sort { $h->{$a}->{AVG} <=> $h->{$b}->{AVG} } keys %$h;
$stash->set('k', \@k);
[% END %]
[% FOREACH name IN k %]
<tr>
<td width="140">[% name.substr(0, 18);%]</td>
<td width="55">[% payload_batting.$name.atts %]</td>
<td width="55">[% payload_batting.$name.runs %]</td>
<td width="55">[% payload_batting.$name.hits %]</td>
<td width="55">[% payload_batting.$name.AVG %]</td>
<tr>
[% END %]
更简洁的是注册一个新的自定义虚拟方法来为您进行排序(文档在此处):
首先,您必须为您定义实现键排序的虚拟方法。这只是一个简单的实现,允许您在结构中按多个级别对嵌套哈希进行排序:
use Template::Stash;
$Template::Stash::HASH_OPS->{'deep_sort'} = sub {
my ($h, $name, $op) = @_;
$op //= 'cmp';
my @fields = split(/\./,$name);
my $resolve = sub {
my $v = $_[0];
foreach (@fields) {
$v = $v->{$_};
}
return $v;
};
return [sort { $resolve->($h->{$a}) cmp $resolve->($h->{$b}) } keys %$h ]
if $op eq 'cmp';
return [sort { $resolve->($h->{$a}) <=> $resolve->($h->{$b}) } keys %$h ]
if $op eq '<=>';
};
然后你必须像这样在模板中引用它:
[% FOREACH name IN payload_batting.deep_sort('AVG','<=>') %]
<tr>
<td width="140">[% name.substr(0, 18);%]</td>
<td width="55">[% payload_batting.$name.atts %]</td>
<td width="55">[% payload_batting.$name.runs %]</td>
<td width="55">[% payload_batting.$name.hits %]</td>
<td width="55">[% payload_batting.$name.AVG %]</td>
<tr>
[% END %]
具有更深数据结构的不同情况:
[%
data = {
payload_batting => { STAT => { AVG => 4, SUM => 16 } }
}
%]
[% data.deep_sort('STAT.AVG','<=>') %]
推荐阅读
- android - Android 动态功能
- php - SESSION_DRIVER=database 时 Laravel 表单响应 HTTP 419
- java - 与现有抽象类 Clock 相比,新接口 java.time.InstantSource 的主要目的是什么?
- angular - 如何使用 Angular 中的单选按钮更改数组值
- python - 将字符串元组设置为 dict 键
- vim - 失去焦点时出现在 Vim 上的 "^[[O"
- git - ArgoCD 无法与“已请求 SSH 代理但未指定 SSH_AUTH_SOCK”同步
- powerbi - 无法从 power-bi 报表生成器数据集中的数据源获取数据
- apache-spark - spark怎么写parquet文件?
- javascript - 使用 ES6 使用属性值过滤数据