Perl的两列的平面文件到复杂的无序列表树 [英] Perl two column flat file to a complex unordered list tree

查看:198
本文介绍了Perl的两列的平面文件到复杂的无序列表树的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对已经被拉从我们的广告结构,看起来像这样,与Manager是第一场的组织结构图的数据文件,与员工第二 - 在某些情况下,管理者会看几个工作人员后,

  __ EXAMPLE__
USER4 user8
user8 USER9
    USER1
用户1用户2
用户2用户3
用户2 USER5
用户2 USER4
用户3 USER5
USER4 user6
USER4 user7
 

这需要在一个HTML无序列表输出像这样的:

 #预期输出
#
#< UL>
#<李>用户1< /李>
#< UL>
#<李>用户2< /李>
#< UL>
#<李>用户3< /李>
#< UL>
#<李> USER5< /李>
#< / UL>
#<李> USER4< /李>
#< UL>
#<李> user6< /李>
#<李> user7< /李>
#<李> user8< /李>
#< UL>
#<李> USER9< /李>
#< / UL>
#< / UL>
#< / UL>
#< / UL>
#< / UL>
 

我想我大概可以使用例如code在此位置:<一href="http://stackoverflow.com/questions/22464214/parse-text-file-and-create-complex-tree-structure-in-perl">Parse文本文件,并在但我努力让最初的例子成需要的格式perl的创建复杂的树状结构。

我有一些code的吸收在整个数据文件到一个数组,检查管理值不为空,然后递归尝试下一个经理树匹配(直到遇到空),这应该给我喜欢的输出:

  USER1
用户1用户2
用户1用户2用户3
用户1用户2用户3 USER5
用户1用户2 USER4
用户1用户2 USER4 user6
用户1用户2 USER4 user7
用户1用户2 USER4 user8
用户1用户2 USER4 user8 USER9
 

不幸的是我的Perl是很生疏,我的code看起来很可怕;我不知道我这个接近的最好方式,所以希望能得到一些智慧的话,从我比别人更聪明。

当前例如:

 #!的/ usr / bin中/ perl的
#
使用严格的;
使用警告;

我@Complete =&lt;数据取代;

我的foreach $行(@Complete){
    格格($行);
    我($佛罗里达州,$ USR)=分流(/ \吨/年,$线); #Formal利德华放;&安培;用户
    我的foreach $领袖(@Complete){
        格格($组长);
        如果($领袖=〜/ $ FL $ /){
            $行= $领袖\ t的$ USR。;
            ($佛罗里达州,$ USR)=分流(/ \吨/年,$线,2);
            $领袖='';
        }
        最后,如​​果($ FL当量'');
    }
    打印'。$行。\ N的;
}

__数据__
USER4 user8
user8 USER9
    USER1
用户1用户2
用户2用户3
用户2 USER5
用户2 USER4
用户3 USER5
USER4 user6
USER4 user7
 

解决方案

下面的程序是接近你想要的:

 使用严格的;
使用警告;

使用HTML ::实体;

分呈现{
    我($ underlings_of,$的水平,$键)= @_;
    我的$手下= $ underlings_of-&GT; {$}键或返回;
    打印,X $的水平,&LT; UL&GT; \ N的;
    我的$下属(排序@ $下属){
        打印X($级+ 1),&LT;李&gt;中,恩code_entities($下属),&LT; /李&GT; \ N的;
        渲染($ underlings_of,$级+ 1,$下属);
    }
    打印,X $的水平,&LT; / UL&GT; \ N的;
}

我的%underlings_of;

而(我的$行= readline的数据){
    终日啃食$线;
    我($经理,$ EMP)=分流/ \吨/年,$线;
    推@ {$ underlings_of {$经理}},$ EMP;
}

渲染(\%underlings_of,0,'');

__数据__
USER4 user8
user8 USER9
    USER1
用户1用户2
用户2用户3
用户2 USER5
用户2 USER4
用户3 USER5
USER4 user6
USER4 user7
 

这将产生以下输出:

&LT; UL&GT;   &LT;李&GT;用户1&LT; /李&GT;   &LT; UL&GT;     &LT;李&GT;用户2&LT; /李&GT;     &LT; UL&GT;       &LT;李&GT;用户3&LT; /李&GT;       &LT; UL&GT;         &LT;李&GT; USER5&LT; /李&GT;       &LT; / UL&GT;       &LT;李&GT; USER4&LT; /李&GT;       &LT; UL&GT;         &LT;李&GT; user6&LT; /李&GT;         &LT;李&GT; user7&LT; /李&GT;         &LT;李&GT; user8&LT; /李&GT;         &LT; UL&GT;           &LT;李&GT; USER9&LT; /李&GT;         &LT; / UL&GT;       &LT; / UL&GT;       &LT;李&GT; USER5&LT; /李&GT;     &LT; / UL&GT;   &LT; / UL&GT; &LT; / UL&GT;

用户 USER5 列出了两次,因为他们出现两次输入的层次结构,在用户2 ,并在用户3 。这意味着你的结构是不是一个真正的树,它是一个有向无环(希望)图。

有关其他的方法, https://en.wikipedia.org/wiki/Topological_sorting 可能是有帮助的,因为我相信你的问题是拓扑排序的一个实例。

I have a data file for an organizational chart that has been pulled from our AD structure and looks like this, with the Manager being the first field, and the employee the second - in some situations a manager will look after a few staff:

__EXAMPLE__
user4   user8
user8   user9
    user1
user1   user2
user2   user3
user2   user5
user2   user4
user3   user5
user4   user6
user4   user7

This needs to be output in a HTML unordered list such as this:

# Intended output
#
# <ul>
#   <li>user1</li>
#   <ul>
#       <li>user2</li>
#       <ul>
#           <li>user3</li>
#           <ul>
#               <li>user5</li>
#           </ul>
#           <li>user4</li>
#           <ul>
#               <li>user6</li>
#               <li>user7</li>
#               <li>user8</li>
#             <ul>
#               <li>user9</li>
#             </ul>
#           </ul>
#       </ul>   
#   </ul>
# </ul>

I've figured I can probably use the example code at this location: Parse Text file and create complex tree structure in perl but I'm struggling to get the initial example into the required format.

I've got some code which sucks the whole datafile into an array, checks the Manager value is not null, then recursively tries to match the next manager up the tree (until it hits the null) which should give me the output like:

user1
user1 user2
user1 user2 user3
user1 user2 user3 user5
user1 user2 user4
user1 user2 user4 user6
user1 user2 user4 user7
user1 user2 user4 user8
user1 user2 user4 user8 user9

Unfortunately my Perl is very rusty and my code looks terrible; I'm not sure I'm approaching this the best way, so was hoping to get some words of wisdom from someone wiser than me.

Current example:

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

my @Complete = <DATA>;

foreach my $line (@Complete) {
    chomp($line);
    my ($fl, $usr) = split(/\t/, $line); #Formal Leader && User
    foreach my $leader (@Complete) {
        chomp($leader);
        if ($leader =~ /$fl$/) {
            $line = $leader."\t".$usr;
            ($fl,$usr) = split(/\t/, $line, 2);
            $leader = '';
        }
        last if ($fl eq '');
    }
    print "'".$line."'\n";
}

__DATA__
user4   user8
user8   user9
    user1
user1   user2
user2   user3
user2   user5
user2   user4
user3   user5
user4   user6
user4   user7

解决方案

The following program is close to what you want:

use strict;
use warnings;

use HTML::Entities;

sub render {
    my ($underlings_of, $level, $key) = @_;
    my $underlings = $underlings_of->{$key} or return;
    print "  " x $level, "<ul>\n";
    for my $underling (sort @$underlings) {
        print "  " x ($level + 1), "<li>", encode_entities($underling), "</li>\n";
        render($underlings_of, $level + 1, $underling);
    }
    print "  " x $level, "</ul>\n";
}

my %underlings_of;

while (my $line = readline DATA) {
    chomp $line;
    my ($mgr, $emp) = split /\t/, $line;
    push @{$underlings_of{$mgr}}, $emp;
}

render(\%underlings_of, 0, '');

__DATA__
user4   user8
user8   user9
    user1
user1   user2
user2   user3
user2   user5
user2   user4
user3   user5
user4   user6
user4   user7

It produces the following output:

<ul>
  <li>user1</li>
  <ul>
    <li>user2</li>
    <ul>
      <li>user3</li>
      <ul>
        <li>user5</li>
      </ul>
      <li>user4</li>
      <ul>
        <li>user6</li>
        <li>user7</li>
        <li>user8</li>
        <ul>
          <li>user9</li>
        </ul>
      </ul>
      <li>user5</li>
    </ul>
  </ul>
</ul>

User user5 is listed twice because they appear twice in the input hierarchy, under user2 and under user3. This means your structure isn't really a tree, it's a directed acyclic (hopefully) graph.

For other approaches, https://en.wikipedia.org/wiki/Topological_sorting may be helpful because I believe your problem is an instance of topological sorting.

这篇关于Perl的两列的平面文件到复杂的无序列表树的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆