How can I completely flatten a Perl 6 list (of lists (of lists) … )
我想知道我如何才能完全扁平化列表和包含它们的东西。除此之外,我还提出了一个解决方案,它可以将具有多个元素的东西放回原处,或者在将其放回原处后再将具有一个元素的东西带走。
这与我如何"扁平化"Perl6中的列表有点不同?这并不是完全平坦的,因为任务是重组。
但是,也许有更好的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | my @a = 'a', ('b', 'c' ); my @b = ('d',), 'e', 'f', @a; my @c = 'x', $( 'y', 'z' ), 'w'; my @ab = @a, @b, @c; say"ab:", @ab; my @f = @ab; @f = gather { while @f { @f[0].elems == 1 ?? take @f.shift.Slip !! @f.unshift( @f.shift.Slip ) } } say"f:", @f; |
这就产生了:
1 2 | ab: [[a (b c)] [(d) e f [a (b c)]] [x (y z) w]] f: [a b c d e f a b c x y z w] |
号
奇怪的是,我还读了一些关于Python的答案:
- 在python中从列表中创建一个简单列表
- 如何将列表扁平化一步
- 将列表列表展平为列表列表
不幸的是,即使子列表包装在项容器中,也没有直接内置的可以完全扁平化数据结构。
一些可能的解决方案:
收集/带走您已经提出了这样的解决方案,但是
1 | sub reallyflat (+@list) { gather @list.deepmap: *.take } |
。自定义递归函数
您可以使用这样的子例程递归地将cx1〔4〕列表导入其父列表:
1 2 | multi reallyflat (@list) { @list.map: { slip reallyflat $_ } } multi reallyflat (\leaf) { leaf } |
另一种方法是递归地将
1 2 3 4 5 6 | sub reallyflat (+@list) { flat do for @list { when Iterable { reallyflat $_<> } default { $_ } } } |
。多维数组索引
1 2 3 4 | say @ab[*;*]; # (a (b c) (d) e f [a (b c)] x (y z) w) say @ab[*;*;*]; # (a b c d e f a (b c) x y z w) say @ab[*;*;*;*]; # (a b c d e f a b c x y z w) say @ab[**]; # HyperWhatever in array index not yet implemented. Sorry. |
。
不过,如果您知道数据结构的最大深度,这是一个可行的解决方案。
避免集装箱化内置的
一个
Array (而不是List )将它的每个元素包装在一个新的物品容器中,不管它以前是否有一个。- 如何避免:如果不需要数组提供的可变性,可以使用列表列表而不是数组数组数组。与
:= 的绑定可以用来代替赋值,将List 存储在@ 变量中,而不将其转换为Array :1
2
3my @a := 'a', ('b', 'c' );
my @b := ('d',), 'e', 'f', @a;
say flat @b; # (d e f a b c)。
- 如何避免:如果不需要数组提供的可变性,可以使用列表列表而不是数组数组数组。与
$ 变量是项目容器。- 如何避免:当在
$ 变量中存储一个列表,然后将其作为元素插入另一个列表时,使用<> 取消对它的初始化。当将父列表的容器传递给flat 时,也可以使用| 绕过父列表的容器:1
2
3my $a = (3, 4, 5);
my $b = (1, 2, $a<>, 6);
say flat |$b; # (1 2 3 4 5 6)。
- 如何避免:当在
我不知道这样做的内置方法,尽管很可能有(如果没有,可能应该有)。
我能在短时间内想出的最好办法是:
1 | gather @ab.deepmap(*.take) |
我不确定collect/take如何与超运算符的潜在并行评估进行交互,因此以下替代方法可能不安全,尤其是在您关心元素顺序的情况下:
1 | gather @ab>>.take |
号
如果需要数组,可以将代码放在方括号中,或者通过
最后,这是第一个重新布线为复古样式子例程的解决方案:
1 | sub deepflat { gather deepmap &take, @_ } |