我有一个数组
my @arr1 = ("A1", "B1,B2", "C1,C2,C3", ..);
如何通过附加元素来创建新数组,以便从@ arr1中获取一个子元素,如A1,B1和& C1创建一个新元素" A1B1C1"。子元素由","分隔。数组元素编号是动态的。
因此生成的数组应该看起来像
@out = qw/A1B1C1 A1B1C2 A1B1C3 A1B2C1 A1B2C2 A1B2C3/;
答案 0 :(得分:7)
您可以执行动态递归或联系CPAN模块,但在这种情况下我会使用glob
:
my @out = glob join '', map "{$_}", @arr1;
答案 1 :(得分:4)
出于某些不可理喻的原因,我厌恶使用glob
来生成这样的交叉产品。我不喜欢在生产代码中使用say
,也许是因为它感觉像是一个调试工具
我认为以这种方式使用glob
并没有错,但除了Zaid's fine answer
很容易假设Math::Combinatorics
或Algorithm::Combinatorics
可以帮助我们。与Graph
一起,其中一个模块是Perl程序员工具箱的一个组件,但它们只能处理一组值,它是多个集合的交叉产品,是必需的这里
我选择了Brian Foy Set::CrossProduct
我的基准测试表明,它比glob
技巧快了约150倍,但这并不重要,除非计算在您尝试优化的应用程序的关键路径上
use strict;
use warnings 'all';
use feature 'say';
use Set::CrossProduct;
my @arr1 = ('A1', 'B1,B2', 'C1,C2,C3');
my $iterator = Set::CrossProduct->new( [ map [ split /,/ ], @arr1 ] );
while ( my $tuple = $iterator->get ) {
say join '', @$tuple;
}
A1B1C1
A1B1C2
A1B1C3
A1B2C1
A1B2C2
A1B2C3
要以与 Zaid 答案插件兼容的方式使用此模块,您可以编写
my @out = map { join '', @$_ } $iterator->combinations;