2010-08-23 30 views
7

Quiero crear matrices de forma dinámica en función de la entrada del usuario. Por ejemplo, si el usuario da entrada como 3, se deben crear tres matrices con el nombre @message1, @message2 y @message3.Crear matrices dinámicamente en Perl

¿Cómo lo hago en Perl?

+0

Probabilidad para la respuesta súper corto : [perllol] (http: // perldoc.perl.org/perllol.html). Incluso Perl tiene LOLz. – Dummy00001

Respuesta

12

Tengo que preguntar por qué quieres hacer esto, porque no es el camino correcto. Si usted tiene tres corrientes de entrada, cada uno de los cuales tiene que ser almacenado como una lista, a continuación, almacenar uno lista, que es una lista de las listas (en el que las listas se almacenan como referencias matriz):

my @input = (
    [ 'data', 'from', 'first', 'user' ], 
    [ qw(data from second user) ], 
    [ qw(etc etc etc) ], 
); 

Si tiene nombres asociados con los datos de cada usuario, es posible que desee utilizar ese como una clave hash, para indexar los datos en contra:

my %input = (
    senthil => [ 'data', 'from', 'first', 'user' ], 
    ether => [ qw(data from second user) ], 
    apu => [ qw(etc etc etc) ], 
); 

por favor refiérase a la Perl Data Structures Cookbook (perldoc perldsc) para obtener más al seleccionar la estructura de datos correcta para la situación y cómo definirlos .

+4

Buena respuesta, excepto que se refiere varias veces a "listas" cuando quiere decir "matrices". En Perl, las listas y matrices no son las mismas cosas. Las listas son datos, las matrices son variables. La diferencia es sutil, pero importante. –

+0

@davorg: Quise decir listas cuando dije listas. Las listas se pueden almacenar como * arrays *, o * arrayrefs *, y también en * hashes *. – Ether

+0

no, en realidad no. las matrices o hashes pueden producir listas o inicializarse desde una lista, pero no exactamente * almacenan * listas. Aún le daría un pase a la "lista almacenada en una matriz", pero la "lista almacenada * como * una matriz" es demasiado engañosa. – ysth

17

No. En su lugar, utilice una matriz de matrices:

my @message; 
my $input = 3; 
for my $index (0..$input-1) { 
    $message[$index][0] = "element 0"; 
    $message[$index][1] = 42; 
} 
print "The second array has ", scalar(@{ $message[1] }), " elements\n"; 
print "They are:\n"; 
for my $index (0..$#{ $message[1] }) { 
    print "\t", $message[1][$index], "\n"; 
} 

Algunas reglas votos están en http://perlmonks.org/?node=References+quick+reference

2

En lenguajes compilados, las variables no tienen un nombre. El nombre que ve en el código es un identificador único asociado con algún desplazamiento numérico. En un identificador como message_2, el '2' solo sirve para que sea un identificador único. Cualquiera puede decir que puede hacer sus tres variables: message_125, message_216 y message_343. Mientras pueda decir qué debe poner en qué, funcionan tan bien como message_1 ...

El "nombre" de la variable es solo para que los mantenga en línea mientras escribe el código.

Los idiomas dinámicos añaden capacidad al no purgar la (s) tabla (s) de símbolos. Pero una tabla de símbolos es simplemente una asociación de un nombre con un valor. Debido a que Perl le ofrece listas y hash de forma económica, no es necesario utilizar el método de programación/logística para realizar un seguimiento de las variables y permitir un acceso flexible en tiempo de ejecución.

probable es que si usted se ve nombrar listas @message1, @message2, ... -, donde los elementos se diferencian solamente por su orden de referencia, que estos nombres son tan buenos: $message[1], $message[2], ....

Además, dado que las tablas de símbolos generalmente se asignan de nombre a desplazamiento (en la pila o en el montón), realmente no es mucho más que un par clave-valor que se encuentra en hash. Así que los hashes funcionan igual de bien para buscar nombres más distintos.

$h{messages} = []; 
$h{replies} = []; 

quiero decir realmente si quisiera, podría almacenar todo lo que se pone en una variable léxica en un solo hash para el alcance, si no le importa la escritura: $h{variable_name} para todo. Pero no obtendría el beneficio de la administración implícita del alcance de Perl, y en todos los idiomas, los programadores preferían la administración implícita del alcance.

Perl permite la manipulación simbólica, pero con los años los lenguajes dinámicos han encontrado una bendición mixta. Pero en Perl tienes ambas "perspectivas", para darles un nombre. Como puede determinar qué código en un lenguaje compilado es probable que funcione mejor que un lenguaje dinámico, se ha determinado que es más libre de errores utilizar una "perspectiva compilada" para más cosas: como puede ver con la disponibilidad de administración de compensación y compilación de búsqueda de comportamiento que se le entregó en Core Perl, no hay razón para meterse con la tabla de símbolos, si no es necesario.

Crear una matriz de forma dinámica, es tan simple como: []. Asignarlo a un lugar en la memoria, cuando no sabemos cuántos queremos almacenar, es tan fácil como:

push @message, []; 

y la creación de una lista de listas a la vez es tan fácil como:

@message = map { [] } 1..$num_lists; 

para un valor especificado en $num_lists.

+2

'([]) x' crea copias múltiples de la misma referencia de matriz; quieres 'map ([], 1 .. $ num_lists)' en su lugar – ysth

+0

@ysth, ya sabes, lo escribí primero con un mapa, pero pensé que el multiplicador parecía más rápido. :) – Axeman

+0

y así es :) – ysth

3

La creación dinámica de nuevas matrices nombradas casi nunca es una buena idea. Mark Dominus, autor del esclarecedor libro Higher-Order Perl, ha escrito un three - partseries detallando las trampas.

tiene nombres en mente para estas matrices, por lo que los pone en un hash:

sub create_arrays { 
    my($where,$n) = @_; 

    for (1 .. $n) { 
    $where->{"message$_"} = []; 
    } 
} 

Para un ejemplo rápido que muestra la estructura, el código de abajo

my $n = @ARGV ? shift : 3; 

my %hash; 
create_arrays \%hash, $n; 

use Data::Dumper; 
$Data::Dumper::Indent = $Data::Dumper::Terse = 1; 
print Dumper \%hash; 

salidas

$ ./prog.pl 
{ 
    'message2' => [], 
    'message3' => [], 
    'message1' => [] 
}

Especificando un número diferente de matrices, obtenemos

$ ./prog.pl 7 
{ 
    'message2' => [], 
    'message6' => [], 
    'message5' => [], 
    'message4' => [], 
    'message3' => [], 
    'message1' => [], 
    'message7' => [] 
}

El orden de las teclas parece extraño porque están dentro de un hash, una estructura de datos desordenada.

Recordemos que [] crea una referencia a una nueva matriz en el anonimato, por lo que, por ejemplo, para añadir valores a Message2, que iba a escribir

push @{ $hash{"message2"} }, "Hello!"; 

Para imprimir, se escribiría

print $hash{"message2"}[0], "\n"; 

Tal vez usted quiere saber cuánto tiempo todas las matrices son:

foreach my $i (1 .. $n) { 
    print "message$i: ", scalar @{ $hash{"message$i"} }, "\n"; 
} 

Por m detalles de mineral sobre el uso de referencias en Perl, consulte la siguiente documentación: