2014-03-27 26 views
0

產生深哈希映射下面是我的代碼以哈希在Perl

#!/usr/bin/perl 
use warnings; 
use JSON::PP; # Just 'use JSON;' on most systems 
my %name = (
      'sl' => { 
        'fsd' => { 
           'conf' => { 
              'ul' => '/sl/fsd/conf/ul', 
              'si' => '/sl/fsd/conf/si', 
              'ho1' => '/sl/fsd/conf/ho1' 
             } 
          } 
        }, 
      're' => { 
        'fsd' => { 
           'cron' => { 
              'README' => '/re/fsd/cron/README' 
             }, 
           'bin' => { 
              'db' => { 
                'smart.p_add_tag' => '/re/fsd/bin/db/smart.p_add_tag', 
                'smart.p_tag_partition' => '/re/fsd/bin/db/smart.p_tag_partition', 
                'smart.p_add_tag_type' => '/re/fsd/bin/db/smart.p_add_tag_type' 
                } 
             }, 
           'doc' => { 
              'SMART' => '/re/fsd/doc/SMART', 
              'README' => '/re/fsd/doc/README' 
             }, 
           'data' => { 
              'README' => '/re/fsd/data/README' 
             }, 
           'conf' => { 
              'al1' => '/re/fsd/conf/al1', 
              'file' => '/re/fsd/conf/file', 
              'ho' => '/re/fsd/conf/ho', 
              'al3' => '/re/fsd/conf/al3', 
              'hst' => '/re/fsd/conf/hst', 
              'us' => '/re/fsd/conf/us', 
              'README' => '/re/fsd/conf/README', 
              'al2' => '/re/fsd/conf/al2' 
             } 
          } 
        } 
     ); 




(my $root) = keys %name; 

my %nodes =(); 
my %tree =(); 
my @queue = ($root); 

list_children(\%name, \@queue, \%nodes) while @queue; 

my $tree = build_tree($root, \%nodes); 

my $json = JSON::PP->new->pretty; # prettify for human consumption 

print $json->encode($tree); 

sub list_children { 
    my $adjac = shift; 
    my $queue = shift; 
    my $nodes = shift; 

    my $node = shift @$queue; 

    my @children = keys %{$adjac->{$node}}; 

    @children = grep { ! exists $nodes->{$_}} @children; 

    $nodes->{$node} = \@children; 

    push @$queue, @children; 
} 

sub build_tree { 
    my $root = shift; 
    my $nodes = shift; 

    my @children; 
    for my $child (@{$nodes->{$root}}) { 
    push @children, build_tree($child, $nodes); 
    } 

    my %h = ('text'  => $root, 
      'children' => \@children); 

    return \%h; 
} 

我試圖輸出JSONified哈希值,但它僅穿越最多兩個級別。而我需要它遍歷每個父代的最後一個子節點。有人可以幫助實現這一目標。

下面是電流輸出

{ 
    "text" : "sl", 
    "children" : [ 
     { 
     "text" : "fsd", 
     "children" : [] 
     } 
    ] 
} 
+2

你試過了什麼?如果您在運行代碼時發佈了一些代碼和結果,您將獲得更多幫助。只是問'給我解決方案'不是一個好主意。 –

+0

謝謝Paul的建議。 我試圖遍歷散列,然後分配每個第二級元素作爲孩子,但它沒有按預期工作,我想出了一個哈希散列的想法。請幫忙。 – rahulsagar

+2

預期的產出不是你想象的。嘗試Data :: Dumper並轉儲值 - 一個哈希不能有多個同名的鍵。 – choroba

回答

1

通常情況下,轉化的哈希,並然後 JSON-ING是不是最有效的辦法,因爲你要做出一個穿越改造哈希和JSON的去做一個json-ify它,而JSON是一種哈希變換。

但是,JSON通常用XS來完成,這意味着至少第二次遍歷更快。這和JSON行爲是標準化的。

use 5.016; 
use strict; 
use warnings; 
use Data::Dumper(); 
use JSON; 

my $hash 
    = { 
    'Foods' => { 
    'fruits' => { 
     'orange' => '1', 
     'apple' => '2', 
    }, 
    'Vegetables' => { 
     'tomato' => '3', 
     'carrot' => '1', 
     'cabbage' => '2', 
    } 
    } 
}; 

sub descend { 
    my ($structure, $block) = @_; 
    my $res; 
    while (my ($k, $v) = each %$structure) { 
     $block->($structure, $k, $v); 
     if (ref($v) eq 'HASH') { 
      $res = descend($v, $block); 
     } 
    } 
    return $res; 
} 

my $new = {}; 
my $curr = $new; 

descend($hash => sub { 
    my ($lvl, $k, $v) = @_; 
    my $node = { text => $k }; 
    $curr->{children} //= []; 
    push $curr->{children}, $node; 

    if (ref($v) eq 'HASH') { 
     $curr = $node; 
    } 
    else { 
     $node->{children} = { text => $v }; 
    } 
}); 

# allow for the root-level special case, and retrieve the first child. 
$new = $new->{children}[0]; 

say Data::Dumper->Dump([ $new ], [ '$new' ]); 
say JSON->new->encode($new); 
+0

感謝您的代碼,但它似乎無法正確識別孩子 – rahulsagar

+0

@rahulsagar,這正是'if(ref($ v)eq'HASH')'正在分支。如果它是一個散列,它不是一個葉節點,否則就是和'children'一起被分配一個散列,其中一個鍵'text'指向該值,如您最初所示。我懷疑它可能是javascript方面的一個問題,其中節點是相似的,但我們有時候爲'children'節點和一個節點組成的數組。 – Axeman