amiribarksdale has asked for the wisdom of the Perl Monks concerning the following question:

I have been trying to convert a bunch of arrayrefs into a list of "rows" suitable for insertion into a DB. But with proper "left" and "right" identifers for a nested set structure. I feel like I am *this* close, but I haven't been able to crack it.

Here's the datastructure:

my $raw_graph = [ 'root', undef, [ "Amiri", "Test tubes are clear.", [ "Darla", "Jump!" ], [ "Jeff", "Daytime." ], ], [ "Ryan", "Oops.", ], ];

Each node has two "content" blocks and then an arbitrary number of arrayrefs, which are of the same structure.

My transform is like this:

explorenode( $raw_graph, [], 1, 1 );
sub explorenode { my ( $node, $rows, $left, $id ) = @_; my $i = $id; my $l = $left; for ( 2 .. $#$node ) { $id++; $left++; explorenode( $node->[$_], $rows, $left, $id ); $id++; $left++; } $left++; push( @$rows, [ $i, $l, $left, $node->[0], $node->[1] ] ); }

@$rows is right only for the first subnode, i.e., Ryan's count is off:

$VAR1 = [ 3, 3, 4, 'Darla', 'Jump!' ]; $VAR2 = [ 5, 5, 6, 'Jeff', 'Daytime.' ]; $VAR3 = [ 2, 2, 7, 'Amiri', 'Test tubes are clear.' ]; $VAR4 = [ 4, 4, 5, 'Ryan', 'Oops.' ]; $VAR5 = [ 1, 1, 6, 'root', undef ];

It should be

$VAR1 = [ 3, 3, 4, 'Darla', 'Jump!' ]; $VAR2 = [ 4, 5, 6, 'Jeff', 'Daytime.' ]; $VAR3 = [ 2, 2, 7, 'Amiri', 'Test tubes are clear.' ]; $VAR4 = [ 5, 8, 9, 'Ryan', 'Oops.' ]; $VAR5 = [ 1, 1, 10, 'root', undef ];

Any help would be eternally appreciated!

Amiri

Replies are listed 'Best First'.
Re: Turn a nested array into a nested set?
by almut (Canon) on Apr 15, 2010 at 19:01 UTC

    Ok, I think I got it.

    #!/usr/bin/perl my $raw_graph = [ 'root', undef, [ "Amiri", "Test tubes are clear.", [ "Darla", "Jump!" ], [ "Jeff", "Daytime." ], ], [ "Ryan", "Oops.", ], ]; my $left = 1; my $id = 1; my $out = []; explorenode( $raw_graph, $out, $left, $id ); print "[ @$_ ]\n" for @$out; sub explorenode { my ( $node, $rows, $l, $i ) = @_; $left++; $id++; for ( 2 .. $#$node ) { explorenode( $node->[$_], $rows, $left, $id ); } push( @$rows, [ $i, $l, $left, $node->[0], $node->[1] ] ); $left++; } __END__ [ 3 3 4 Darla Jump! ] [ 4 5 6 Jeff Daytime. ] [ 2 2 7 Amiri Test tubes are clear. ] [ 5 8 9 Ryan Oops. ] [ 1 1 10 root ]
      Oh my God!!! Thank you, almut!!!! Can I buy you a beer or something! Thanks.
Re: Turn a nested array into a nested set?
by almut (Canon) on Apr 15, 2010 at 18:09 UTC

    It's not immediately clear to me how your expected values are meant to come about (and judging by the fact that no one else has replied yet, I might not be the only one :).  For example, could you elaborate why it should be 8 and 9 in

    $VAR4 = [ 5, 8, 9, 'Ryan', 'Oops.' ];

    (I suppose the first value is some row ID, reflecting the sequence in which the arrays are encountered while traversing the structure)