perl - 哈希的所有可能组合

Den*_*erZ 1 perl hash combinations

告诉我如何获得所有可能的哈希组合

这是一个例子

my %data = (
'a' => [qw(a1 a2 a3)],
'b' => [qw(b1 b2 b3)],
'c' => [qw(c1 c2 c3)]);
Run Code Online (Sandbox Code Playgroud)

要得到

a1
a2
a3
b1
b2
b3
c1
c2
c3

a1 b1
a1 b2
a1 b3
a1 c1
a1 c2
a1 c3

b1 c1
b1 c2
b1 c3
b2 c1
b2 c2
b2 c3
b3 c1
b3 c2
b3 c3

a1 b1 c1
a1 b1 c2
a1 b1 c3
a1 b2 c1
a1 b2 c2
a1 b2 c3
a1 b3 c1
a1 b3 c2
a1 b3 c3
a2 b1 c1
a2 b1 c2
a2 b1 c3
a2 b2 c1
a2 b2 c2
a2 b2 c3
a2 b3 c1
a2 b3 c2
a2 b3 c3
a3 b1 c1
a3 b1 c2
a3 b1 c3
a3 b2 c1
a3 b2 c2
a3 b2 c3
a3 b3 c1
a3 b3 c2
a3 b3 c3
Run Code Online (Sandbox Code Playgroud)

谢谢

DVK*_*DVK 6

使用brian d foy的Set::CrossProduct模块.您需要以明显的方式将哈希按到阵列数组中.

use Set::CrossProduct;
my $iterator = Set::CrossProduct->new( ARRAY_OF_ARRAYS );
my $tuples = $iterator->combinations;
Run Code Online (Sandbox Code Playgroud)


Eri*_*rom 5

我的模块List :: Gen包含一个cartesian可以产生你想要的结果的函数.这段代码似乎可以解决问题,但是你的例子并没有包含这将产生的所有排列,我假设这只是一个例子中的遗漏.

use List::Gen 'cartesian';

my %data = (
    'a' => [qw(a1 a2 a3)],
    'b' => [qw(b1 b2 b3)],
    'c' => [qw(c1 c2 c3)],
);

my $product = cartesian {join ' ' => sort grep defined, @_}
              map {[@$_, undef]} 
              values %data;

say for sort {length $a <=> length $b or $a cmp $b} @$product;
Run Code Online (Sandbox Code Playgroud)

这有点密集,所以要解释一下:

  • values %data 返回数组 %data
  • map {[@$_, undef]} 然后在每个末尾附加一个空值,因为你想要部分组合
  • cartesian {join ' ' => sort grep defined, @_} 然后完成工作的主要内容,计算数组的笛卡尔积,同时减去未定义的元素,并按照示例显示对值进行排序.
  • sort {length $a <=> length $b or $a cmp $b} @$product 然后按指定的顺序打印出产品.