如何彻底平整Perl 6列表(列表(列表)…)
我想知道我如何能够完全压扁包含它们的列表和内容.除此之外,我想出了这样一个解决方案,它将有不止一个元素的东西放回去,或者在滑倒之后用一个元素来处理东西.
这与How do I “flatten” a list of lists in perl 6?有点不同,因为任务是重组,这并不完全平坦. 但是,也许有更好的方法. 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; 这给出: 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的答案: > Making a flat list out of list of lists in Python itertools.chain(*子列表)看起来很有趣,但答案是递归的,或者限于硬编码的两个级别.功能语言在源代码中递归,但我预计. 解决方法
不幸的是,即使子列表被包装在项目容器中,也没有直接的内置功能可以完全平坦化数据结构.
一些可能的解决方案: 收集/取 您已经提出了这样的解决方案,但是deepmap可以处理所有的树式迭代逻辑来简化它.对于数据结构的每个叶节点,它的回调被调用一次,因此使用take作为回调方法,即收集将收集叶值的平面列表: sub reallyflat (+@list) { gather @list.deepmap: *.take } 自定义递归函数 您可以使用这样的子程序将列表递归递送到父级中: multi reallyflat (@list) { @list.map: { slip reallyflat $_ } } multi reallyflat (leaf) { leaf } 另一种方法是递归地应用<到子列表中释放他们包装的任何物品容器,然后调用结果: sub reallyflat (+@list) { flat do for @list { when Iterable { reallyflat $_<> } default { $_ } } } 多维数组索引 postcircumfix []运算符可以与多维下标一起使用,以获得一定长度的叶节点的平面列表,尽管不幸的是“无限深度”版本尚未实现: 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. 但是,如果您知道数据结构的最大深度,这是一个可行的解决方案. 避免集装箱化 内置的平面功能可以平滑一个深入嵌套的列表列表.问题在于它不会下降到项目容器(Scalars)中.嵌套列表中无意的项目容器的常见来源有: >一个数组(但不是列表)将其每个元素包装在一个新的项目容器中,无论以前是否有一个元素. >如何避免:使用列表而不是数组数组,如果您不需要Array提供的可变性.绑定:=可以使用而不是赋值,将列表存储在@变量中,而不将其转换为数组: my @a := 'a','c' ); my @b := ('d',@a; > $变量是项容器. >如何避免:将列表存储在$变量中,然后将其作为元素插入到另一个列表中时,使用<>去掉它.也可以使用|绕过父列表的容器当把它传递给平: my $a = (3,4,5); my $b = (1,2,$a<>,6); say flat |$b; # (1 2 3 4 5 6) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |