假设我想要从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)]
?
假设我想要从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)]
?
还可以参考一种更好的方式来实现我(OP)想要的。
还可以参考“如何完全展平Raku列表(列表(列表)……)”问题的“一些可能的解决方案”答案。
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变量,因为我认为对于不熟悉Raku的人来说,这样更清晰。
我没有将下标附加到原始表达式上,但我本可以这样做:
my \perm = <a b c>.combinations(2)».permutations[*;*];
say perm; # ((a b) (b a) (a c) (c a) (b c) (c b))
[*;*]
技巧来“展平”列表,但我不喜欢无Sigil变量,这对于那些了解Perl(5或6)的人来说非常不清晰。 - mscha最终,您一开始就以错误的方式构建了列表。您可以像这样将排列插入外部列表中。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)[*;*]
<a b c>.combinations(2).map(*.permutations.Slip).Array
[ slip .permutations for <a b c>.combinations(2) ]
Seq
,则调用.Array
是不必要的,并且可以用.list
或.cache
(由PositionalBindFailover提供)替换,如果不需要可变性。|
运算符代替slip
子。.hyper
调用;另外请注意,在你的例子中,组合列表被迭代了两次。 - Christoph.Slip
就是我需要的技巧。很遗憾.Slip
似乎不起作用... - mscha».permutations
部分也不会起作用。 - mschapermutations
方法被注释为 nodal
特征(参见Any.pm
,List.pm
),防止超级运算符执行深度映射(参见metaops.pm
,查找METAOP_HYPER_POSTFIX
);不确定用户文档是否解释了这一点,但在设计文档中提到了。 - Christophmy @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。在长列表上进行映射可能需要很长时间。
.Slip
是我需要的技巧。很遗憾 ».Slip
似乎不起作用... - mscha