perl - 在 Template Toolkit 中按值而不是键对哈希引用进行排序

标签 perl dancer 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 %]

更简洁的方法是注册一个新的自定义虚拟方法来为您进行排序(文档为 here ):

首先,您必须定义为您实现键排序的虚拟方法。这只是一个简单的实现,允许您按结构中的多个级别对嵌套哈希进行排序:

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','<=>') %]

关于perl - 在 Template Toolkit 中按值而不是键对哈希引用进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63947696/

相关文章:

perl - 为什么 `|`(管道)上的拆分未按预期工作?

perl - 如何访问 Dancer2 的 session 对象?

database - 如何避免每个perl文件中的数据库连接信息

perl:如何使用 select AND fork 处理多个套接字?

javascript - 如何在 Dancer 中找到数据文件的路径以在 Javascript 中使用?

html - 在现代 Perl Web 框架中动态生成 HTML

perl - 如何使用Template Toolkit打印递归数据结构?

perl - 如何将 undef 作为参数从 TT 模板传递给对象方法?

mysql - Perl:在 Perl-Hash 中存储来自 Mysql 表的列