2010-06-15 18 views
11

¿El operador de bucle foreach de Perl requiere que los elementos de la lista se presenten en orden?Perl, orden de pedido

Por ejemplo

my @a=(1,2,3); 

foreach my $item (@a) { 
print $item; 
} 

siempre imprimir 1 2 3?

Sospecho que sí, pero no puedo encontrarlo documentado.

Respuesta

14

Sí. Se repite en el orden de la lista. la medida en que está documentado, mira perldoc perlsyn:

El foreach itera bucle sobre un valor de la lista normal y establece el VAR variable de sea cada elemento de la lista, a su vez.

"A su vez" aquí significa en orden.

+10

Tenga en cuenta también que el orden de las teclas en un hash no está definido ni ordenado. Las listas siempre se ordenan en cualquier lugar donde se usan. – Daenyth

+0

no solo no está definido, sino que está explícitamente aleatorizado en versiones recientes de perl para aumentar la seguridad –

+0

@Eric Me morderé: ¿cuál es el problema de seguridad? – Telemachus

3

Sí, lo hará. Las matrices y las listas están ordenadas.

3

Sí, los arreglos conservan el orden, mientras que los hash no.

7

Sí.

Alguna complejidad aparente (las matrices están en orden, pero los hash no son - ¿WTF?) Proviene del hecho de que la mayoría de las respuestas están ignorando la importancia de contexto.

Las variables, funciones, operadores y subrutinas de Perl pueden evaluar valores diferentes según el contexto. El contexto puede ser escalar o lista.

En contexto escalar, solo queremos un valor. Por ejemplo, my $count = @array; asigna el número de elementos en @array a $count, porque la asignación a un escalar proporciona un contexto escalar.

En el contexto de la lista, estamos buscando valores múltiples. Por ejemplo, my @merged = @left, @right;. La asignación a una matriz proporciona contexto de lista, por lo que @left y @right se expanden en una lista de sus elementos. Como las listas son estructuras planas, tenemos una larga lista que combina elementos de ambas matrices. Finalmente, la lista de valores se asigna a @merged.

La razón por la que la mayoría de las respuestas no aclaran esto es que, aunque el contexto parece extraño al principio, el 99% del tiempo funciona de forma transparente y hace lo que cabría esperar.

El lazo for proporciona un contexto de lista. Esto significa que lo que está dentro del paréntesis se interpreta en el contexto de la lista. La lista resultante se repite en orden.

Lo que esto significa es que:

  • for (@array) {} se expande la matriz en la lista de elementos, preservando el orden de la matriz.
  • for (%hash) {} expande el hash en una lista ordenada aleatoriamente de pares clave/valor.
  • for (<FILEHANDLE>) {} lee todas las líneas disponibles en Filehandle y las presenta en orden.
  • for (some_subroutine()) {} evalúa some_subroutine() en el contexto de la lista y repite los resultados.
Cuestiones relacionadas