Присоединение к массиву массивов

У меня есть массив @ary неизвестного размера. Каждый элемент, $ary[$i], является arrayref неизвестного размера. Каждый элемент этого, $ary[$i][$j]это строка.

Я хочу объединить все $ary[0][$j] со всеми $ary[1][$j] со всеми... и так далее.

То есть предположим, что мой массив выглядит так:

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

Тогда я бы хотел return быть:

(
'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'
)

(В качестве альтернативы return может быть массивом arrayrefs: (['foo', 'bar', 'baz'], ['foo', 'bar', 'zun'], …).)

Как я могу это сделать?

2 ответа

Решение

Я бы предложил начать с массива индексов, а затем повторить все комбинации:

#!/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;
            }
        }
    }
}

Результаты:

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

Существуют модули cpan для такой комбинации, но они не знают их от руки.

Я сделал это, и это сработало:

#!/usr/bin/perl
use strict;
use warnings;

my @arry= ();
$arry[0] = ['foo', 'fun'];
$arry[1] = ['bar', 'bun', 'blip'];
$arry[2] = ['baz', 'zun'];

my @combos = ();
$combos[0] = [''];

for my $i (1 .. @arry) {
  for my $j (0 .. @{$combos[$i - 1]} - 1) {
    push @{$combos[$i]}, "$combos[$i - 1][$j] $_" for @{$arry[$i - 1]};
  }
}
my @goodcombos = @{$combos[-1]};
s/^ // for @goodcombos;
print "$_\n" for @goodcombos;

Создает необходимые конкатенации, сохраняя первые термины в $combos[1], конкатенации первых 2 членов в $combos[2], конкатенации первых 3 членов в $combos[3], и так далее.

Другие вопросы по тегам