Here is something interesting I found through playing around with map, my favorite Perl toy. I've not the faintest if this could be useful in a more general way or if it's just, well, interesting crap...

Here's how it emerged:

Just as an exercise, I wanted to generate a list of strings with a specific length from every possible combination of a list of characters.

But not with for loops, but with nested maps! In its simplest form, with 2 chars and strings with a length of two:

my @a = qw( a b ); my @b = map { my $x = $_; map { $x . $_ } @a; } @a;

This produces aa, ab, ba, bb.

Adding characters is easy:

my @a = qw( a b c );

This produces aa, ab, ac, ba, bb, bc, ca, cb, cc.

But increasing the length of the string is not so easy. I did this by adding another nested map:

my @b = map { my $x = $_; map { my $y = $_; map { $x . $y . $_ } @a; } @a; } @a;

which, with qw( a b ), produces aaa, aab, aba, abb, baa, bab, bba, bbb. This is, of course, stupid.

One way to solve this problem is with a recursive function:

sub f { my ( $n, @a ) = @_; croak "illegal value for n: $n" if $n < 1; return @a if $n == 1; map { my $x = $_; map { $x . $_ ) } f( $n - 1, @a ); } @a; }

Now you could make it more general by adding a coderef parameter, string concatenation being only a special case needed in the original example:

sub f { my ( $n, $g, @a ) = @_; croak "illegal value for n: $n" if $n < 1; return @a if $n == 1; map { my $x = $_; map { $g->( $x, $_ ) } f( $n - 1, $g, @a ); } @a; }

So we have a function f that produces a list b by applying a function g to all possible combinations of a list a by calling itself recursively n times.

Is this useful? Or could it be further transformed so that it yields something useful?


In reply to nested maps by jczeus

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.