How do I “flatten” a list of lists in perl 6?

By inserting slips as appropriate, eg via

<a b c>.combinations(2).map(*.permutations.Slip).Array

or

[ slip .permutations for <a b c>.combinations(2) ]

Invoking .Array in the first example is unnecessary if you're fine with a Seq, and can be replaced with calls to .list or .cache (supplied by PositionalBindFailover) if mutability is not needed.

In the second example, the prefix | operator could be used instead of the slip sub.


Ultimately, you are building your list the wrong way to begin with. You can slip your permutations into the outer list like this.

<a b c>.combinations(2).map(|*.permutations);

Which yields the following list

((a b) (b a) (a c) (c a) (b c) (c b)) 

According to the Bench module, this is about 300% faster than doing

<a b c>.combinations(2).map(*.permutations)[*;*]

See also "a better way to accomplish what I (OP) wanted".

See also "Some possible solutions" answer to "How can I completely flatten a Raku list (of lists (of lists) … )" question.

Add a subscript

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)

Notes

I used a non-sigil'd variable because I think it's a bit clearer what's going on for those who don't know Raku.

I didn't append the subscript to the original expression but I could have:

my \perm = <a b c>.combinations(2)».permutations[*;*];
say perm;       # ((a b) (b a) (a c) (c a) (b c) (c b))

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")]␤»

However, you may be better of to destructure the LoL when you use it later in the program. A map on a long list can take a jolly long time.

Tags:

Raku