這是我在Perl中使用Template Toolkit編寫的東西,但它更像是一個通用算法問題。我的基本問題是,給定的數據結構是這樣的:構建「內省」嵌套html表
my @array = (
[qw /00 01/],
[qw /10/],
[qw /20 21/],
[qw /30 31 32 33 /],
);
我需要像這樣輸出(簡化圖):
<00>
<10>
<20> <30>(00/10/20/30)</30> <31>(00/10/20/31)</31>
<32>(00/10/20/32)</32> <33>(00/10/20/30)</33>
</20>
<21> <30>(00/10/21/30)</30> <31>(00/10/21/31)</31>
<32>(00/10/21/31)</32> <33>(00/10/21/31)</33>
</21>
</10>
</00>
<01>
<10>
<20> <30>(01/10/20/30)</30> <31>(01/10/20/31)</31>
<32>(01/10/20/32)</32> <33>(01/10/20/33)</33>
</20>
<21> <30>(01/10/21/30)</30> <31>(01/10/21/31)</31>
<32>(01/10/21/32)</32> <33>(01/10/21/33)</33>
</21>
</10>
</01>
這是屬於嵌套HTML表格的簡化示例實際產出。中心節點處的路徑實際上是要調用另一個子例程以使用數據填充嵌套表的參數。我相當肯定原始數組結構的轉置是有用的,所以我寫了Array::Transpose::Ragged並在今天早些時候在CPAN上發佈了它。
我管理一個從內部到外部構建嵌套結構的實現(使用perl的Template Toolkit - 見下文),但是當我到達結構的外部部分時,我不再有機會填充中央節點需要的數據。下面是它的價值是實現:
爲了興趣,我想我應該把TT版本:
[% SET inner = "(path data should go here)" %]
[% MACRO process_groups(line, inner) BLOCK %]
[% FOREACH l IN line %]
<[% l %]>[% inner %]</[% l %]>
[% END %]
[% END %]
[% WHILE (x = records.pop) %]
[% inner = process_groups(x, inner) %]
[% END %]
[% inner %]
對我應該採取得到這個權利
更新的方法有什麼建議的接受答案。有點棘手,因爲TT心不是相當的Perl作爲靈活,但這裏有雲:
#!/usr/bin/env perl
use warnings;
use strict;
use Template;
my $template = Template->new();
my @array = (
[ qw/00 01/ ], [ qw/10/ ],[ qw/20 21/ ], [ qw/30 31 32 33/ ]);
my $stash = { records => \@array, };
$template->process(\*DATA, $stash) || die $template->error(), "\n";
__END__
[% MACRO print_output(data, path_elements) BLOCK; %]
[% current = data.0; remaining = data.slice(1); %]
[% FOREACH d IN current %]
<[% d %]>
[% IF remaining.size > 0 %]
[% path_elements.push(d); print_output(remaining, path_elements); %]
[% SET discard = path_elements.pop %]
[% ELSE %]
([% path_elements.join('/') _ '/' _ d %])
[% END %]
</[% d %]>
[% END %]
[% END %]
[% SET path = []; print_output(records, path) %]
更妙的是這裏是在TT的實際嵌套表結構:
[% MACRO print_output(data, path_elements) BLOCK; %]
<table> <tr>
[% current = data.0; remaining = data.slice(1); %]
[% FOREACH d IN current %]
<th>[% d %]</th>
[% END %] </tr>
<tr>
[% FOREACH d IN current %]
[% IF remaining.size > 0 %]
<td id="[% d %]">[% path_elements.push(d); print_output(remaining, path_elements); %]</td>
[% SET discard = path_elements.pop %]
[% ELSE %]
<td>([% path_elements.join('/') _ '/' _ d %])</td>
[% END %]
[% END %]
</tr></table>
[% END %]
[% SET path = []; print_output(records, path) %]
這基本上是與格式列表組成的問題,對不對? – Axeman 2010-11-04 15:55:28