in reply to Combinations of lists to a hash

No recursion needed.

You could regex your input to form a glob pattern:

main::(-e:1): 0 DB<1> x <Prefix1={A,B}:{c,d}> 0 'Prefix1=A:c' 1 'Prefix1=A:d' 2 'Prefix1=B:c' 3 'Prefix1=B:d' DB<2> @keys = <Prefix1={A,B}:{c,d}> DB<3> @hash{@keys} = ('value1') x @keys

> (which I'd rather not bore you with)

That's a bad approach because first it wasn't clear for me what you are trying to achieve.

Especially because %hash = {...} is broken Perl. :)

HTH!

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Update

A demo to build the glob pattern:

DB<22> ($pre,@comb) = split /=|:/, "Prefix1=A,B:c,d" DB<23> p $pattern = "$pre=" . join ":", map { "{$_}" } @comb Prefix1={A,B}:{c,d} DB<24> x <"$pattern"> 0 'Prefix1=A:c' 1 'Prefix1=A:d' 2 'Prefix1=B:c' 3 'Prefix1=B:d' DB<25>

NB: You should take care to properly escape potential meta characters like * or ?

Replies are listed 'Best First'.
Re^2: Combinations of lists, etc
by AnomalousMonk (Archbishop) on Oct 04, 2019 at 15:17 UTC

    Here's an | another (just saw tybalt89's post)  s/// approach to building the globulation string:

    c:\@Work\Perl\monks>perl -wMstrict -MData::Dump -le "my %globize = ('=' => '={', ':' => '}:{', '' => '}'); ;; my $globule = 'Prefix2=A:b,c:1,2'; $globule =~ s{ ([=:] | \z) }{$globize{$1}}xmsg; print qq{'$globule'}; ;; my @globs = glob $globule; dd \@globs; " 'Prefix2={A}:{b,c}:{1,2}' [ "Prefix2=A:b:1", "Prefix2=A:b:2", "Prefix2=A:c:1", "Prefix2=A:c:2", ]
    Is this any better?   (shrugs)   (haukex's Building Regex Alternations Dynamically technique might be an interesting general approach to building the  s/// pattern, but the curly at the end of the string would present a minor problem.)


    Give a man a fish:  <%-{-{-{-<

      Nice work, AnomalousMonk, thank you!
      I tried that in a script, getting it to read all the lines of data, and it works perfectly!  See below.

      I'm now trying to change it so it handles the 4 updates in my original post.  I see it already handles update #1 re the '*'. How does it do that, given that you're using glob?

      Below is your code as a full script with my attempted changes to make it process all the data, and to handle updates #3 & #4 commented out because they don't work.  Any suggestions on how to get them working?  And how to best fit update #2 in to your code?

      And how is '' => '}' replacing the line ending?  I know \z matches the end, but those empty 'quotes' puzzle me.

      #!/usr/bin/perl use strict; use warnings; my %globize = ('=' => '={', ':' => '}:{', '' => '}'); #my %globize = ('?What here?' => '{', ':' => '}:{', '' => '}'); my (@globs, %hash); while (<DATA>) { my ($globule, $value) = split / /; chomp $value; $globule =~ s{ ([=:] | \z) }{$globize{$1}}xmsg; #$globule =~ s{ (\A | : | \z) }{$globize{$1}}xmsg; print qq{'$globule'}."\n"; @globs = glob $globule; $hash{$_} = $value for @globs; } use Data::Dump; dd \%hash; __DATA__ Prefix1:A,B:c,d value1=10 Prefix2:A:b,c:1,2 value2=20 Prefix3:A:*:1,2 value3=30 Prefix4:A:*:1,2 value4a=10|value4b=20 Prefix5,Prefix6:A:*:1,7 value5=10
        And how is '' => '}' replacing the line ending? I know \z matches the end, but those empty 'quotes' puzzle me.

        That's easy enough to explain. In essence, it's a bit of regex affectation. The idea was to stick a }-curly on the end of a string. That can be done well enough with a
            $string .= '}';
        statement, but I thought it would be neat to it with the same global substitution that was handling all the other transformations. The empty pattern matches the empty string, and the empty string is present n+1 times in a string of n length.

        c:\@Work\Perl\monks\tel2>perl -wMstrict -le "my $s = '123'; $s =~ s{ }{X}xmsg; print qq{A: '$s'}; ;; $s = ''; $s =~ s{ }{X}xmsg; print qq{B: '$s'}; ;; $s = '123'; $s =~ s{ \z }{X}xmsg; print qq{C: '$s'}; " A: 'X1X2X3X' B: 'X' C: '123X'
        And there's always an empty string at the  \z (absolute end) of any string, even the empty string! (And the empty string is a perfectly good hash key.)

        As you have seen, this approach breaks down when you try to replace an empty string at different locations with different replacement strings: there can only be one ''-keyed value in a hash. To do what you want with a regex, you'd have to resort to some screaming hack like (untested)

        my %globize = ('P' => '{P', ':' => '}:{', '' => '}'); ... $globule =~ s{ (\A P | : | \z) }{$globize{$1}}xmsg;
        (in the unlikely case your input string always starts with a fixed sequence like 'P'), but if you just want to add different stuff at the start and end of a string, it would be better IMHO to just do something like
            $globule = "{$globule}";
        instead (update: and forget about all the  \z alternation and  '' => '}' stuff).


        Give a man a fish:  <%-{-{-{-<

Re^2: Combinations of lists, etc
by The Perlman (Scribe) on Oct 04, 2019 at 16:23 UTC
    > NB: You should take care to properly escape potential meta characters like * or ?

    Is there a trivial way to do this?

    - Ron

      In general, meta-quoting for regexes (as used in split) can be done with quotemeta or with the  \Q ... \E intepolation escape sequences (see Quote and Quote-like Operators), which work for both double-quote and regex interpolation.


      Give a man a fish:  <%-{-{-{-<

        Are you sure this works with File::Glob 's meta characters sufficiently well?

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

      Something like    s/[][\\?*{},]/\\$&/g might do. (Untested)

      But in the case that I'd worry about such input I'd rather write a loop multiplying arrays.

      That's easier to test. :)

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

        Which tool exactly fulfills the OP's requirements? Could you demonstrate?
        - Ron