in reply to Re: An iterator for (not "iterating") a recursive data structure.
in thread An iterator for (not "iterating") a recursive data structure.

This [...] only works if undef is not a possible value, and empty arrays are not possible.

It doesn't even handle false values (without a minor change).

The following handles false values (including undef) as well as empty arrays:

sub genIterator { my $array = shift; my $index = 0; # Current index into $array my $child_iter; # Iterator for array at $array[$index] return sub { while (1) { # If we're iterating through descendants of a child, if (defined $child_iter) { # If the there is a descendant we haven't returned, if ( my ($element) = $child->() ) { return $element; } # No more descendants for this child. $child_iter = undef; } # Signal end of iteration if done. return if $index >= @$array; # Return next child if it's not an array ref. my $element = $array->[$index++]; return $element if ref $element ne 'ARRAY'; # Prepare to iterate through descendants of child. $child_iter = genIterator($element); } } } my $iter = genIterator \@nested; say while ($_) = $iter->();
  • Comment on Re^2: An iterator for (not "iterating") a recursive data structure.
  • Download Code

Replies are listed 'Best First'.
Re^3: An iterator for (not "iterating") a recursive data structure.
by Eily (Monsignor) on Jul 09, 2019 at 07:08 UTC

    ++. It looks like I forgot to test my code for false values (it took me a while to see where they wouldn't work, it was the very last line where I iterate while the value is true).

    Thanks for the correction, for some reason I'm still not sure I would have thought of it even nowadays. I suppose I don't really think about using the number of returned values when I'm expecting a scalar, rather than a list

        ... OK, I'll have to seriously train myself to use that idiom.