NAME
NestedMap - a module to make nesting map{}s inside map{}s easier
SYNOPSIS
# show all combinations of (A,B,C) (a,b,c) and (1,2,3)
print join("\n",
nestedmap {
nestedmap {
nestedmap {
join('',@NestedMap::stack[0..2])
} qw(A B C)
} qw(a b c)
} qw(1 2 3)
);
# a zip() function for any number of lists of varying length
sub zipn {
my @args = @_;
[
nestedmap {
nestedmap {
defined($args[$_][$NestedMap::stack[1]]) ?
$args[$_][$NestedMap::stack[1]] :
''
} 0..$#args
} 0 .. max(map { $#{$_[$_]} } 0..$#args)
]
}
NB - older versions of perl may not like the code blocks I use in these examples. You may have to use:
nestedmap sub { ... }, @list;
instead of
nestedmap { ... } @list;
See the test suite for examples of the above code modified to use that syntax.
DESCRIPTION
Perl's map{} function is very useful, but ain't so great when you try to put map{}s inside map{}s, as inner maps can have no idea what the outer map{}s are doing. NestedMap solves that, by maintaining a stack of all the nested map{}s' ideas of what $_ is. It's useful if you want to iterate over lists of lists.
It exports one function into your namespace ...
- nestedmap
-
This function takes any number of arguments, the first of which must be a coderef (ie, either a reference to a subroutine, or an anonymous subroutine). That subroutine should take one argument. It will be called once for each of the remaining arguments given to nestedmap(). The return value of nestedmap() is a list of all the return values of the user-supplied subroutine Within your subroutine, $_ is available just like in an ordinary map{}. There is also an array called @NestedMap::stack which lets you get at the 'parent' nestedmaps' values of $_. The first element (element 0) is your own $_, the second is the parent's, the third is the grandparent's, and so on. Yes, you can change them. That would be considered evil. And funny.
HOW IT DIFFERS FROM map{}
Because nestedmap() is a subroutine, as is the user-supplied function, then unlike with map{} (which is a perl built-in) the value of @_ will not remain the same inside a pile of nestedmap()s. If you want to refer to the same @_ throughout, then you will need to assign @_ to another variable first. See the zipn() example in the synopsis above.
BUGS
No bugs are known, but if you find any please let me know, and send a test case.
FEEDBACK
I welcome feedback about my code, including constructive criticism. And, while this is free software (both free-as-in-beer and free-as-in-speech) I also welcome payment. In particular, your bug reports will get moved to the front of the queue if you buy me something from my wishlist, which can be found at http://www.cantrell.org.uk/david/shopping-list/wishlist.
AUTHOR
David Cantrell <david@cantrell.org.uk>
COPYRIGHT
Copyright 2003 David Cantrell
This module is free-as-in-speech software, and may be used, distributed, and modified under the same terms as Perl itself.