in reply to A maybe(?) interesting comp-sci type problem
#!/usr/bin/perl use strict; use warnings; use DBIx::Iterator qw(mk_iterator list_iterator); my $data_struct = [ ...snip...(see OP) ]; my $iter = flatten($data_struct); while ( my @row = $iter->() ) { print "@row\n"; } sub flatten { my $data = shift; my $iter = mk_iterator(_flatten(0, $data)); sub { my $data = $iter->() or return; return @$data{sort { $a <=> $b } keys %$data}; } } sub _flatten { my ($i, $data) = @_; my @tmp = @$data; my @groups = (); while (@tmp) { my @nxt_group; push @nxt_group, shift @tmp while @tmp > 2 and !ref($tmp[1]); push @nxt_group, @tmp and @tmp=() if @tmp <= 2 and !grep ref($_), @tmp; if ( @nxt_group ) { push @groups, [ mk_list_iter($i, @nxt_group) ]; } if ( @tmp ) { my @nxt_grp; push @nxt_grp, mk_list_iter($i, shift(@tmp)); push @nxt_grp, _flatten($i+1, shift(@tmp)) while @tmp and ref($tmp[0]); push @groups, [ @nxt_grp ]; } } return @groups; } sub mk_list_iter { my ($i, @list) = @_; sub { list_iterator( LIST => [ map { [$_] } @list ], SELECT => [ $i ], @_ ); } }
|
|---|