Perl   发布时间:2022-04-04  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了如何彻底平整Perl 6列表(列表(列表)…)大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我想知道我如何能够完全压扁包含它们的列表和内容.除此之外,我想出了这样一个解决方案,它将有不止一个元素的东西放回去,或者在滑倒之后用一个元素来处理东西.

这与How do I “flatten” a list of lists in perl 6?有点不同,因为任务是重组,这并不完全平坦.

但是,也许有更好的方法.

@H_461_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
> How flatten a list of lists one step
> flatten list of lists of lists to a list of lists

itertools.chain(*子列表)看起来很有趣,但答案是递归的,或者限于硬编码的两个级别.功能语言在源代码中递归,但我预计.

解决方法

不幸的是,即使子列表被包装在项目容器中,也没有直接的内置功能可以完全平坦化数据结构.

一些可能的解决方案:

收集/取

您已经提出了这样的解决方案,但是deepmap可以处理所有的树式迭代逻辑来简化它.对于数据结构的每个叶节点,它的回调被调用一次,因此使用take作为回调方法,即收集将收集叶值的平面列表:

sub reallyflat (+@list) { gather @list.deepmap: *.take }

自定义递归函数

您可以使用这样的子程序将列表递归递送到父级中:

@H_461_6@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;
say flat @b; # (d e f a b C)

> $变量是项容器.

>如何避免:将列表存储在$变量中,然后将其作为元素插入到另一个列表中时,使用<>去掉它.也可以使用|绕过父列表的容器当把它传递给平:

my $a = (3,4,5);
my $b = (1,2,$a<>,6);
say flat |$b;  # (1 2 3 4 5 6)

大佬总结

以上是大佬教程为你收集整理的如何彻底平整Perl 6列表(列表(列表)…)全部内容,希望文章能够帮你解决如何彻底平整Perl 6列表(列表(列表)…)所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。