http://www.perlmonks.org?node_id=278030


in reply to recursive complex structure or something like that?

I established a dictionary where each term can have children. The actual rooted structure is a tree. Or what Zaxo said. You have to watch out for circular references in my code.

my %dict; # A reverse index on %dict by id. while (my $line = <$fh>) { my ( $id, $parent, $term ) = split ' ', $line, 3; # Fixed from -3 +per sauoq $dict{$id}{'id'} = $id; $dict{$id}{'parent'} = $parent; push @{$dict{$parent}{'children'}}, $dict{$id}; } use Data::Dumper; print Dumper( \ %dict );

Or with the circular reference problem nixed

use Util::Scalar 'weaken'; my %dict; # A reverse index on %dict by id. while (my $line = <$fh>) { my ( $id, $parent, $term ) = split ' ', $line, 3; # Fixed per sauo +q $dict{$id}{'id'} = $id; $dict{$id}{'parent'} = $parent; push @{$dict{$parent}{'children'}}, $dict{$id}; weaken $dict{$parent}{'children'}[-1]; } use Data::Dumper; print Dumper( \ %dict );

Replies are listed 'Best First'.
Re: Re: recursive complex structure or something like that?
by sauoq (Abbot) on Jul 26, 2003 at 02:27 UTC
    = split ' ', $line, -3;

    You almost certainly want

    = split ' ', $line, 3;
    not -3.

    -sauoq
    "My two cents aren't worth a dime.";
    
Re: Re: recursive complex structure or something like that?
by Isanchez (Acolyte) on Jul 28, 2003 at 22:48 UTC

    Dear Saint Diotalevi

    thank you so much for your reply,

    I used the input file:

    1 0 domestic_animal 2 1 dog 3 2 terrier 4 2 collie 5 3 fox_terrier
    I used your code (only modified for input):
    $in = "sample.txt"; open (IN, $in) or die "cant open the in\n"; # my %dict; # A reverse index on %dict by id. # my %dict; # A reverse index on %dict by id. while (not eof (IN)) { $line = <IN>; my ( $id, $parent, $term ) = split (' ', $line, 3) ; $dict{$id}{'id'} = $id; $dict{$id}{'parent'} = $parent; push @{$dict{$parent}{'children'}}, $dict{$id}; } use Data::Dumper; print Dumper( \ %dict );

    and this is what i get:

    $VAR1 = { '4' => { 'parent' => '2', 'id' => '4' }, '1' => { 'parent' => '0', 'children' => [ { 'parent' => '1', 'children' => [ { 'parent' => '2' +, 'children' => [ + { + 'parent' => '3', + 'id' => '5' + } ] +, 'id' => '3' }, $VAR1->{'4'} ], 'id' => '2' } ], 'id' => '1' }, '3' => $VAR1->{'1'}{'children'}[0]{'children'}[0], '0' => { 'children' => [ $VAR1->{'1'} ] }, '2' => $VAR1->{'1'}{'children'}[0], '5' => $VAR1->{'1'}{'children'}[0]{'children'}[0]{'children' +}[0] };

    what I would need is a print out such that each mother term has all its descendents printed to right.

    Am I doing something wrong?

    Thank you very much, Ivo

      No, its just that the code I originally provided doesn't assume we know what the root is. If you follow $dict{1} you'll notice that everything works out alright. So the data is correct, you just may be mistaken on what you think the correct answer is (and that also handles cycles. You should use my second example with weaken(). The first example leaks memory).