Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 我如何才能完全展平一个列表(列表的列表)_List_Raku_Flatten - Fatal编程技术网

List 我如何才能完全展平一个列表(列表的列表)

List 我如何才能完全展平一个列表(列表的列表),list,raku,flatten,List,Raku,Flatten,我想知道我怎样才能把列表和包含它们的东西完全展平。除此之外,我还提出了一个解决方案,可以将包含多个元素的内容放回原处,或者在放回原处后再使用一个元素进行处理 这有点不同于,它不是完全平坦的,因为任务是重组 但是,也许有更好的办法 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

我想知道我怎样才能把列表和包含它们的东西完全展平。除此之外,我还提出了一个解决方案,可以将包含多个元素的内容放回原处,或者在放回原处后再使用一个元素进行处理

这有点不同于,它不是完全平坦的,因为任务是重组

但是,也许有更好的办法

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的答案:


itertools.chain(*sublist)
看起来很有趣,但答案要么是递归的,要么是硬编码的两个级别。函数式语言在源代码中是递归的,但我预料到了这一点。

我不知道有一种内置的方法可以做到这一点,尽管可能有(如果没有,可能应该有)

我能在短时间内想出的最好办法是:

gather @ab.deepmap(*.take)
我不确定gather/take如何与超级运算符的潜在并行计算交互,因此使用以下替代方法可能不安全,特别是如果您关心元素顺序的话:

gather @ab>>.take
如果需要数组,可以将代码放在方括号中,也可以通过
.list
将其具体化到列表中

最后,这是第一个作为复古风格子程序重新编写的解决方案:

sub deepflat { gather deepmap &take, @_ }

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

一些可能的解决办法:

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

sub reallyflat(+@list){gather@list.deepmap:*.take}
自定义递归函数 您可以使用这样的子例程递归地
列表滑入其父列表:

multi-reallyflat(@list){@list.map:{slip-reallyflat$}
多实平面(\leaf){leaf}
另一种方法是递归地将
应用于子列表,以将它们从包装在其中的任何项目容器中释放出来,然后对结果调用
flat

sub reallyflat(+@list){
@list的单位do{
当Iterable{reallyflat$}
默认值{$}
}
}
多维数组索引
postcircumfix[]
操作符可与多维下标一起使用,以获得达到某个深度的叶节点平面列表,但遗憾的是,“无限深度”版本尚未实现:

说@ab[*]#(a(b c)(d)ef[a(b c)]x(y z)w)
说@ab[*;*].#(a b c d e f a(b c)x y z w)
说@ab[*;*;*].#(a b c d e f a b c x y z w)
说@ab[**]#数组索引中的超链接尚未实现。很抱歉
不过,如果您知道数据结构的最大深度,这是一个可行的解决方案

避免集装箱化 内置的
flat
函数可以很好地展平嵌套很深的列表。问题在于它不会下降到项目容器中(
Scalar
s)。嵌套列表中意外项目容器的常见来源为:

  • 一个
    数组
    (而不是
    列表
    )将它的每个元素包装在一个新的项目容器中,不管它以前是否有一个元素

    • 如何避免:如果不需要数组提供的可变性,请使用列表列表而不是数组数组。使用
      :=
      绑定可以代替赋值,将
      列表
      存储在
      @
      变量中,而不将其转换为
      数组
    • my @a := 'a', ('b', 'c' ); my @b := ('d',), 'e', 'f', @a;
      say flat @b; # (d e f a b c)

嘿,我在写我的答案时,没有看到你已经提出了相同的
deepmap
解决方案。。。是的,一旦
>
学会了像设计文档所期望的那样并行化自身,您的第二个解决方案很可能不会以正确的顺序返回元素。[x]删除了迷信的大括号(并添加了
deepflat
实现)是否有可能添加这样的
deepflat
功能(或者操作符,我指定
|
它还没有被使用)到6.d?我有点喜欢使用没有大括号/括号的现有内置函数:
说gather@ab.deepmap:.take;
@raiph:看起来更漂亮。更新了。@mscha建议Larry的意图是保留前缀:“在分号级别将列表插入分号列表”deepflat的预期解决方案是
[**]
subscript.deepmap FTW。至于“避免使用容器”,有时你必须接受别人给你的东西。最好的解决方案可以解决所有问题。 my $a = (3, 4, 5); my $b = (1, 2, $a<>, 6);
say flat |$b; # (1 2 3 4 5 6)