让我们说我想要a,b和c中的2个字母的所有排列。
我能做到:
my @perm = <a b c>.combinations(2)».permutations;
say @perm;
# [((a b) (b a)) ((a c) (c a)) ((b c) (c b))]
这很接近,但不完全是我需要的。 我如何“扁平化”这样才能得到:
# [(a b) (b a) (a c) (c a) (b c) (c b)]
答案 0 :(得分:14)
另见"a better way to accomplish what I (OP) wanted"。
my \perm = <a b c>.combinations(2)».permutations;
say perm; # (((a b) (b a)) ((a c) (c a)) ((b c) (c b)))
say perm[*]; # (((a b) (b a)) ((a c) (c a)) ((b c) (c b)))
say perm[*;*]; # ((a b) (b a) (a c) (c a) (b c) (c b))
say perm[*;*;*] # (a b b a a c c a b c c b)
我使用了非sigil变量,因为我认为对于那些不了解Perl 6的人来说,情况会更清楚。
我没有将下标附加到原始表达式,但我可以:
my \perm = <a b c>.combinations(2)».permutations[*;*];
say perm; # ((a b) (b a) (a c) (c a) (b c) (c b))
答案 1 :(得分:9)
通过适当插入slips,例如通过
<a b c>.combinations(2).map(*.permutations.Slip).Array
或
[ slip .permutations for <a b c>.combinations(2) ]
如果您使用.Array
,则无需在第一个示例中调用Seq
,并且可以使用.list
或.cache
(由{提供)替换{3}})如果不需要可变性。
在第二个示例中,可以使用前缀|
运算符代替slip
子。
答案 2 :(得分:9)
最终,您正在以错误的方式构建列表。您可以slip
将您的排列设置到外部列表中。
<a b c>.combinations(2).map(|*.permutations);
产生以下列表
((a b) (b a) (a c) (c a) (b c) (c b))
根据Bench模块,这比执行
快约300%<a b c>.combinations(2).map(*.permutations)[*;*]
答案 3 :(得分:4)
my @perm = <a b c>.combinations(2)».permutations;
dd [ @perm.map(*.Slip) ]
# OUTPUT«[("a", "b"), ("b", "a"), ("a", "c"), ("c", "a"), ("b", "c"), ("c", "b")]»
但是,您稍后在程序中使用它时可能更好地解构LoL。长名单上的地图可能需要很长时间。