从嵌套哈希中创建UL

时间:2014-03-17 17:01:19

标签: perl recursion hash

嗨我有一个看起来像这样的哈希。这是使用对数据库的RoseDB调用生成的,然后使用循环压缩:

$data =   'Default'=> {
                        'Record' => {
                                      'PInner' => 1,
                                      'LOuter' => 1,
                                      'POuter' => 1,
                                    },
                        'Elect' => {
                                      'LTurn' => 1,
                                      'RTurn' => 1,
                                      'L'=> 1,
                                       'R'=> 1,
                                    },
                      }

我必须从它做一个无序列表,它看起来像:

<ul>
 <li>Default
 <ul>
     <li>Record
     <ul>
         <li>PInner</li>
         <li>LOuter</li>
         <li>POuter</li>
     </ul>
     </li>
     <li>Elect
          <ul>
              <li> LTurn </li>
              <li> RTurn </li>
              <li> L     </li>
              <li> R     </li>
          </ul>
     </li>
</ul>
</li>

我可以简单地遍历这个并制作一个长杂乱的代码片段。但是当我试图使它成为通用的时候出现问题,而不是我有3个级别&#34; n&#34;水平。所以我想到了使用递归循环。无论如何都有可能实现这一目标

请指教 感谢

2 个答案:

答案 0 :(得分:1)

您不能在没有括号(对于哈希变量)或大括号(对于标量变量)的情况下分配哈希。

这可以满足您的需求,请记住,散列键没有排序,因此列表中的项目可能会以不同的顺序出现。如果有问题,请使用数组而不是哈希值。

#!/usr/bin/perl
use warnings;
use strict;


my %data = ( Default => {
                         Record => {
                                    PInner => 1,
                                    LOuter => 1,
                                    POuter => 1,
                                   },
                         Elect => {
                                   LTurn => 1,
                                   RTurn => 1,
                                   L     => 1,
                                   R     => 1,
                                  },
                        });


listify(0, %data);

sub listify {
    my ($level, %data) = @_;
    print '  ' x $level, "<ul>\n";
    for my $k (keys %data) {
        print '  ' x $level, '  <li>', $k, "</li>\n";
        if (ref $data{$k}) {
            listify($level + 1, %{ $data{$k} });
        }
    }
    print '  ' x $level, "</ul>\n";
}

答案 1 :(得分:0)

这个程序将完成我认为你需要的工作。您在问题中显示的所需输出不是有效的HTML,因此我创建了我认为您的意思。

请注意,Perl哈希本质上是无序的,因此您的值不会被排序。

use strict;
use warnings;

my $data =   {
  Default => {
    Record => { PInner => 1, LOuter => 1, POuter => 1 },
    Elect  => { LTurn => 1, RTurn => 1, L => 1, R => 1 },
  },
};

make_ul($data);

sub make_ul {
  my ($data, $level) = (@_, 0);
  my $tab = '  ';
  my $indent = $tab x $level;

  print "$indent<ul>\n";
  while (my ($key, $val) = each %$data) {
    print "$indent$tab<li>$key</li>\n";
    make_ul($val, $level + 1) if ref $val eq 'HASH';
  }
  print "$indent</ul>\n";
}

<强>输出

<ul>
  <li>Default</li>
  <ul>
    <li>Elect</li>
    <ul>
      <li>RTurn</li>
      <li>LTurn</li>
      <li>R</li>
      <li>L</li>
    </ul>
    <li>Record</li>
    <ul>
      <li>LOuter</li>
      <li>PInner</li>
      <li>POuter</li>
    </ul>
  </ul>
</ul>