in reply to Re: Generating lists of strings
in thread Generating lists of strings

That looks like a lot like the implementation of NestedLoop. Might as well use it.

use Algorithm::Loops qw( NestedLoops ); my @digits = (1..3); NestedLoops( [ (\@digits) x 4 ], sub { print( @_, "\n" ); }, );

Update: In addition to the above, this node originally said that BrowerUk's output was wrong and had code to fix the problem, but I was looking at a reply that produced incorrect output, not the OP. The incorrect version was removed.

Replies are listed 'Best First'.
Re^3: Generating lists of strings
by BrowserUk (Patriarch) on Jan 24, 2010 at 19:51 UTC
    NestedLoop. Might as well use it.

    Your choice for your code. I much prefer the far simpler syntax of nFor.

    And, I think that the mirror between the syntax of nFor and the built-ins map & grep, makes my version far more familiar and digestable (though much less flexible), than the tortuous documentation for NestedLoops which I've still never wrapped by brain around.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      I much prefer the far simpler syntax of nFor.

      And nothing's stopping you from providing that interface.

      #! perl -slw use strict; use Algorithm::Loops qw( NestedLoops ); sub nFor(&@) { my $cb = shift; NestedLoops([ map [ 0..$_-1 ], @_ ], $cb); } my @digits = 1 .. 3; nFor { print join '', @digits[ @_ ]; } ( 3 ) x 4;

      than the tortuous documentation for NestedLoops which I've still never wrapped by brain around.

      Say you want

      apple, dog, 1 apple, dog, 2 apple, dog, III apple, cat, 1 apple, cat, 2 apple, cat, III apple, platypus, 1 apple, platypus, 2 apple, platypus, III orange, dog, 1 orange, dog, 2 orange, dog, III orange, cat, 1 orange, cat, 2 orange, cat, III orange, platypus, 1 orange, platypus, 2 orange, platypus, III tomato, dog, 1 tomato, dog, 2 tomato, dog, III tomato, cat, 1 tomato, cat, 2 tomato, cat, III tomato, platypus, 1 tomato, platypus, 2 tomato, platypus, III
      from
      # Variable number of lists of variable length my @lists = ( [qw( apple orange tomato )], [qw( dog cat platypus )], [qw( 1 2 III )], );

      That's what NestedLoops is for:

      local $, = ", "; local $\ = "\n"; NestedLoops(\@lists, sub { print @_ });

      nFor would require:

      local $, = ", "; local $\ = "\n"; nFor { print map $lists[$_][ $_[$_] ], 0..$#_; } map 0+@$_, @lists;

      Maybe you wouldn't have a problem understanding NestedLoops if it provided a map-ish interface?

      sub nested(&@) { my $cb = shift; NestedLoops(\@_, $cb); } local $, = ", "; local $\ = "\n"; nested { print @_; } @lists;

      Update: Switched initial line to something less rude.

        What does that have to do with anything?

        Everything!

        First: Had I found the NestedLoops() syntax intelligable, I might never have sought my own solution, but as is, I would never have come up with the right syntax to do what you've done.

        Second: The application I originally wrote nFor() for needed to be as efficient as possible:

        c:\test>junk94 Took 0.557000 c:\test>nfor Took 0.09644

        Given the very essence of the problems these routines are designed to handle is deeply nested algorithms, that nearly 6x difference can become very significant. Plus, if I need to tweak the function for specific purposes, my code is infinitely simpler to modify than NestedLoops().


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

        For the record, the above modified-out-of-all-recognition post originally contained following which is entirely different in both content and tone:

        What does that have to do with anything?

        #! perl -slw use strict; use Algorithm::Loops qw( NestedLoops ); sub nFor(&@) { my $cb = shift; NestedLoops([ map [ 0..$_-1 ], @_ ], $cb); } my @digits = 1 .. 3; nFor { print join '', @digits[ @_ ]; } ( 3 ) x 4;

        nFor would require:

        local $, = ", "; local $\ = "\n"; nFor { print map $lists[$_][ $_[$_] ], 0..$#_; } map 0+@$_, @lists;

        Baloney! You just like complicated don't you.

        All that's needed is the intuative:

        my @list1 = qw( apple orange tomato ); my @list2 = qw( dog cat platypus ); my @list3 = qw( 1 2 III ); nFor{ print join ' ', $list1[ $_[0] ], $list2[ $_[1] ], $list3[ $_[2] ], } ( 3 ) x 3;

        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.