2012-07-16 43 views
0

有沒有人有使用Tree::Simple或將數據放入Perl樹中的經驗?Build Tree ::文件數據中的簡單對象

說我有以下數據CSV文件: -

Bob, Bill, Ben, Brett 
Bob, Bill, Brian 
Bob, John, Jim 
Alice, John, Jill, Jane 
Alice, Jean 
Alice, Janet, Brian 

我想將它轉化成一個樹狀結構,以獲取以下信息:

1, Bob 
2, Alice 
1.1, Bill 
1.1.1, Ben 
1.1.1.1, Brett 
1.1.2, Brian 
1.2, John 
1.2.1, Jim 
2.1, John 
2.1.1, Jill 
2.1.1.1, Jane 
2.2, Jean 
2.3, Janet 
2.3.1, Brian 

我已經看過Tree::Simple並知道如果我可以將數據導入樹中,我可以使用Tree::Parser以正確的編號輸出它。

我想要的是一個如何可以逐行輸入數據的例子。我可以從將文件的每一行讀入數組開始,並將$array[0]作爲第一個孩子添加 - 例如,

$tree->addChildren(Tree::Simple->new($array[0])); 

什麼我不知道該怎麼做的是:

  1. 檢查是否存在已是一個在樹名孩子,讓我不加說鮑勃在兩次。

  2. 找到每個孩子這麼正確的父是說吉爾輸入爲約翰的孩子誰是愛麗絲的孩子,而不是鮑勃

    的孩子

我更上欣賞一些幫助這個問題。我一直在爲此工作4天,無法到達那裏。如果Tree::Simple不是這樣做的最好方式,也許還有另一種方式?

+0

請注意,您的數據有,例如,約翰爲Alice和Bob雙方的兒子。 'Tree :: Simple'實現不支持多父節點的n元樹。這是一個問題還是你的數據不具代表性? – Borodin 2012-07-16 15:02:15

回答

1

該程序將讀取您在DATA文件句柄中顯示的示例數據,並顯示您所需的內容。

它通過將樹中的所有節點放置在由每個節點的值索引的散列中來跟蹤它們。每當輸入文件中出現一個值時,就會檢查散列是否已經存在。如果沒有,則創建一個新的樹節點並將其添加到散列中。無論哪種方式,該節點都被用作同一行上下一個值的父代。

沒有檢查數據的一致性,並假定每個節點最多隻有一個父節點。如果數據文件中的某個值第二次出現在另一個父名下方,則新關聯將被忽略。

use strict; 
use warnings; 

use Tree::Simple; 
use Tree::Parser; 

my %nodes; 

my $root = Tree::Simple->new('root'); 

while (<DATA>) { 
    my $parent = $root; 
    for my $name (split) { 
    $name =~ tr/,//d; 
    $nodes{$name} = Tree::Simple->new($name, $parent) unless $nodes{$name}; 
    $parent = $nodes{$name}; 
    } 
} 

my $tp = Tree::Parser->new($root); 
$tp->useDotSeparatedLevelFilters; 
print "$_\n" for $tp->deparse 

__DATA__ 
Bob, Bill, Ben, Brett 
Bob, Bill, Brian 
Bob, John, Jim 
Alice, John, Jill, Jane 
Alice, Jean 
Alice, Janet, Brian 

輸出

1 Bob 
1.1 Bill 
1.1.1 Ben 
1.1.1.1 Brett 
1.1.2 Brian 
1.2 John 
1.2.1 Jim 
1.2.2 Jill 
1.2.2.1 Jane 
2 Alice 
2.1 Jean 
2.2 Janet 
+0

非常感謝您的幫助 - 這讓我想起了重複具有相同價值的節點的問題。但是,如果他們有不同的父母,我確實需要保留重複的價值 - 即約翰需要作爲鮑勃的孩子和愛麗絲的孩子出現;而傑恩需要成爲愛麗絲的孫子,而不是鮑勃的孫子 - 我只是不知道該怎麼做。 – fbc 2012-07-16 15:23:35

+0

然後你選擇了錯誤的數據結構。正如我所說的,n-ary樹中的節點只能有一個父節點。解決方法是*不*添加具有相同值但是不同父項的第二個節點,但是在推薦不同的處理方式之前,您必須解釋您的目的。一旦你建立了它,你想要做什麼?你說這是「爲了獲得[編號輸出]」,但顯然還有更多。 – Borodin 2012-07-16 15:31:21

+0

我的程序必須爲第三方包提供輸入,它使用它來創建網頁上的下拉式分層菜單和子菜單。 因此,例如會有2個頂級菜單,bob和alice,並且這些頂級菜單中的每一個都有一個子菜單john。雖然兩者都叫約翰,但他們實際上是不同的項目。 子子菜單項jill將作爲joice的子菜單進入,該子菜單是alice的子菜單,但不是bob的子菜單。 數據必須以格式的文件進入程序: - 數字,數據,父母號碼例如 1,bob,0 2,alice,0 1.1。,bill,1 1.1.1,ben,1.1 – fbc 2012-07-16 16:18:36