usos sirve que programar para lenguaje español define caracteristicas list perl6 flatten raku

sirve - ¿Cómo puedo aplanar completamente una lista de Perl 6(de listas(de listas)...)



perl wikipedia español (2)

Desafortunadamente, no hay una incorporación directa que aplane completamente la estructura de datos, incluso cuando las sub-listas están envueltas en contenedores de elementos.

Algunas posibles soluciones:

Recoger / tomar

Ya ha encontrado una solución como esta, pero deepmap puede encargarse de toda la lógica de iteración de árbol para simplificarla. Se llama a su devolución de llamada una vez para cada nodo de hoja de la estructura de datos, por lo que usar take como medio de devolución de llamada que gather recopilará una lista plana de los valores de hoja:

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

Función recursiva personalizada

Podría usar una subrutina como esta para slip recursivamente las listas a sus padres:

multi reallyflat (@list) { @list.map: { slip reallyflat $_ } } multi reallyflat (/leaf) { leaf }

Otro enfoque sería aplicar de forma recursiva <> a las sub-listas para liberarlos de los contenedores de elementos en los que están envueltos, y luego llamar flat al resultado:

sub reallyflat (+@list) { flat do for @list { when Iterable { reallyflat $_<> } default { $_ } } }

Indexación multidimensional de matrices

El operador postcircumfix [ ] se puede usar con un subíndice multidimensional para obtener una lista plana de nodos de hoja hasta una cierta profundidad, aunque desafortunadamente la versión de "profundidad infinita" aún no está implementada:

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.

Sin embargo, si conoce la profundidad máxima de su estructura de datos, esta es una solución viable.

Evitar la contenedorización

La función flat incorporada puede aplanar una lista de listas profundamente anidadas bien. El problema es que no desciende a los contenedores de elementos ( Scalar s). Las fuentes comunes de contenedores de elementos no intencionales en listas anidadas son:

  • Una Array (pero no la List ) envuelve cada uno de sus elementos en un contenedor de elementos nuevos, sin importar si tenía uno antes.

    • Cómo evitarlo: use Listas de listas en lugar de Arrays of Arrays, si no necesita la mutabilidad que proporciona Array. La vinculación con := se puede usar en lugar de la asignación, para almacenar una List en una variable @ sin convertirla en un Array :

      my @a := ''a'', (''b'', ''c'' ); my @b := (''d'',), ''e'', ''f'', @a;
      say flat @b; # (d e f a b c)

  • $ variables son contenedores de elementos.

    • Cómo evitarlo: Cuando almacene una lista en una variable $ y luego la inserte como un elemento en otra lista, use <> para descongelarla. El contenedor de la lista de padres también se puede omitir usando | Al pasarlo al flat :

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

Me preguntaba cómo podría aplanar completamente las listas y las cosas que las contienen. Entre otras cosas, se me ocurrió esta solución que desliza las cosas que tienen más de un elemento y las vuelve a colocar, o las toma con un elemento después de deslizarla.

Esto es un poco diferente a ¿Cómo "aplano" una lista de listas en Perl 6? , que no es completamente plana porque la tarea es reestructurar.

Pero, tal vez hay una mejor manera.

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;

Esto da:

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]

Curiosamente, también leí algunas respuestas de python:

  • Hacer una lista plana de la lista de listas en Python
  • Cómo aplanar una lista de listas un paso
  • Aplanar la lista de listas de listas a una lista de listas

itertools.chain(*sublist) parece interesante, pero las respuestas fueron recursivas o se limitaron a dos niveles de codificación rígida. Los lenguajes funcionales eran recursivos en el código fuente, pero esperaba eso.


No conozco una forma integrada de hacerlo, aunque podría haberlo (y si no, probablemente debería haberlo).

Lo mejor que pude encontrar en poco tiempo es esto:

gather @ab.deepmap(*.take)

No estoy seguro de cómo interactuar recopilación / toma con la evaluación potencialmente paralela de los operadores de hiperactivos, por lo que la siguiente alternativa podría no ser segura de usar, en particular si le importa el orden de los elementos:

gather @ab>>.take

Puede poner el código entre corchetes si necesita una matriz o volver a clasificarlo en una lista a través de .list .

Por último, esta es la primera solución rewitten como una subrutina de estilo retro:

sub deepflat { gather deepmap &take, @_ }