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

后端 未结 4 2069
鱼传尺愫
鱼传尺愫 2020-12-09 19:11

Let\'s say I want all permutations of 2 letters out of a, b and c.

I can do:

my @perm = .combinations(2)».permutations;
say @perm;
# [((         


        
相关标签:
4条回答
  • 2020-12-09 19:39
    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.

    0 讨论(0)
  • 2020-12-09 19:51

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

    See also "Some possible solutions" answer to "How can I completely flatten a Perl 6 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 Perl 6.

    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))
    
    0 讨论(0)
  • 2020-12-09 19:51

    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)[*;*]
    
    0 讨论(0)
  • 2020-12-09 20:02

    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.

    0 讨论(0)
提交回复
热议问题