If you have a recursive data structure -- say an AoA[oA[oA]...]] -- and you want to iterate over the leaves; then the typical Perl solution is a recursive callback iterator something like this:
#! perl -slw use strict; use Data::Dump qw[ pp ]; sub genNested { my $n = shift; map{ rand() < 0.5 ? [ rand(1000), genNested( $n-1 ) ] : rand( 1000 + ) } 1 .. $n; } sub cbIterator (&$) { my( $code, $tree ) = @_; for my $i ( 0 .. $#$tree ) { if( ref( $tree->[ $i ] ) eq 'ARRAY' ) { &cbIterator( $code, $tree->[ $i ] ); } else { local $_ = $tree->[ $i ]; $code->(); } } } my @nested = genNested( 3 ); pp \@nested; cbIterator{ print; } \@nested; __END__ C:\test\nhash>nestedIterator.pl [ [ "711.822509765625", "334.869384765625", ["942.19970703125", ["600.4638671875"]], ], "978.3935546875", "965.240478515625", ] 711.822509765625 334.869384765625 942.19970703125 600.4638671875 978.3935546875 965.240478515625
Which is fine unless you need to be able to quit the iteration at an arbitrary point. (ie. short circuit rather completing the full iteration).
What I need is an iterative iterator for a recursive data structure. What I've got so far is this:
#! perl -slw use strict; use Data::Dump qw[ pp ]; sub genNested { my $n = shift; map{ rand() < 0.5 ? [ rand(1000), genNested( $n-1 ) ] : rand( 1000 + ) } 1 .. $n; } sub genIterator { my $tree = shift; my @stack = [ $tree, 0 ]; return sub { ## Fill in the blank (please :). } } my @nested = genNested( 3 ); pp \@nested; my $iter = genIterator( \@nested ); while( my $next = $iter->() ) { last if $next == $something; ## do stuff with $next. }
But my mind's gone blank. Any offers for how to fill the blank?
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |