Search code examples
arraysperlarrayref

Joining an array of arrays


I have an array @ary of unknown size. Each element, $ary[$i], is an arrayref of unknown size. Each element of that, $ary[$i][$j], is a string.

I wish to concatenate all of the $ary[0][$j] with all of the $ary[1][$j] with all of the… and so on.

That is, suppose my array looks like this:

$ary[0] = ['foo', 'fun'];
$ary[1] = ['bar', 'bun', 'blip'];
$ary[2] = ['baz', 'zun'];

Then I'd want the return to be:

(
'foo bar baz',
'foo bar zun',
'foo bun baz',
'foo bun zun',
'foo blip baz',
'foo blip zun',
'fun bar baz',
'fun bar zun',
'fun bun baz',
'fun bun zun',
'fun blip baz',
'fun blip zun'
)

(Alternatively, the return could be an array of arrayrefs: (['foo', 'bar', 'baz'], ['foo', 'bar', 'zun'], …).)

How can I do this?


Solution

  • I would suggest starting with an array of indexes, and then iterate through all combinations:

    #!/usr/bin/env perl
    
    use strict;
    use warnings;
    use feature qw(say);
    
    my @array = (
        [qw(foo fun)],
        [qw(bar bun blip)],
        [qw(baz zun)],
    );
    
    my @index = (0) x @array;
    
    SET:
    while (1) {
        my @set = map { $array[$_][ $index[$_] ] } (0 .. $#index);
    
        say "@set";
    
        $index[-1]++;
    
        for my $i (reverse 0 .. $#index) {
            if ($index[$i] > $#{ $array[$i] }) {
                $index[$i] = 0;
                if ($i > 0) {
                    $index[$i - 1]++;
                } else {
                    last SET;
                }
            }
        }
    }
    

    Results:

    foo bar baz
    foo bar zun
    foo bun baz
    foo bun zun
    foo blip baz
    foo blip zun
    fun bar baz
    fun bar zun
    fun bun baz
    fun bun zun
    fun blip baz
    fun blip zun
    

    There are cpan modules to do this type of combination, but don't know them off hand.