Buscar el tamaño de una matriz en Perl


Parece que me he encontrado con varias formas diferentes de encontrar el tamaño de una matriz. ¿Cuál es la diferencia entre estos tres métodos?

my @arr = (2);
print scalar @arr; # First way to print array size

print $#arr; # Second way to print array size

my $arrSize = @arr;
print $arrSize; # Third way to print array size
 230
Author: Peter Mortensen, 2011-09-13

11 answers

La primera y la tercera forma son las mismas: evalúan un array en contexto escalar. Consideraría que esta es la forma estándar de obtener el tamaño de una matriz.

La segunda forma realmente devuelve el último índice de la matriz, que no es (normalmente) el mismo que el tamaño de la matriz.

 220
Author: Chris Jester-Young,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-09-13 18:44:05

Primero, el segundo no es equivalente a los otros dos. $#array devuelve el último índice de la matriz, que es uno menos que el tamaño de la matriz.

Los otros dos son prácticamente los mismos. Simplemente está utilizando dos medios diferentes para crear contexto escalar. Se trata de una cuestión de legibilidad.

Personalmente prefiero lo siguiente:

say 0+@array;          # Represent @array as a number

Lo encuentro más claro que

say scalar(@array);    # Represent @array as a scalar

Y

my $size = @array;
say $size;

Este último se ve bastante claro por sí solo, pero me parece que la línea extra quita claridad cuando forma parte de otro código. Es útil para enseñar lo que @array hace en contexto escalar, y tal vez si desea usar $size más de una vez.

 34
Author: ikegami,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-01 23:42:21

Esto obtiene el tamaño forzando la matriz a un contexto escalar, en el que se evalúa como su tamaño:

print scalar @arr;

Esta es otra forma de forzar el array a un contexto escalar, ya que está siendo asignado a una variable escalar:

my $arrSize = @arr;

Esto obtiene el índice del último elemento en la matriz, por lo que en realidad es el tamaño menos 1 (suponiendo que los índices comienzan en 0, que es ajustable en Perl aunque hacerlo suele ser una mala idea):

print $#arr;

Este último no es realmente bueno para utilizar para obtener el tamaño de la matriz. Sería útil si solo desea obtener el último elemento de la matriz:

my $lastElement = $arr[$#arr];

También, como puedes ver aquí en Stack Overflow, esta construcción no es manejada correctamente por la mayoría de los resaltadores de sintaxis...

 27
Author: Nate C-K,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-03 08:13:54

Los tres dan el mismo resultado si modificamos el segundo un poco:

my @arr = (2, 4, 8, 10);

print "First result:\n";
print scalar @arr; 

print "\n\nSecond result:\n";
print $#arr + 1; # Shift numeration with +1 as it shows last index that starts with 0.

print "\n\nThird result:\n";
my $arrSize = @arr;
print $arrSize;
 5
Author: Zon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-23 04:32:07

Ejemplo:

my @a = (undef, undef);
my $size = @a;

warn "Size: " . $#a;   # Size: 1. It's not the size
warn "Size: " . $size; # Size: 2
 5
Author: dimas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-03 08:15:51

Para usar la segunda manera, agregue 1:

print $#arr + 1; # Second way to print array size
 5
Author: jhoanna,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-03 08:16:23

La sección "Tipos de variables Perl" de la documentación de perlintro contiene

La variable especial $#array le indica el índice del último elemento de un array:

print $mixed[$#mixed];       # last element, prints 1.23

Usted podría estar tentado a usar $#array + 1 para decirle cuántos elementos hay en una matriz. No te molestes. Como sucede, usando @array donde Perl espera encontrar un valor escalar ("en contexto escalar") le dará el número de elementos en la array:

if (@animals < 5) { ... }

La documentación de perldata también cubre esto en la sección "Valores escalares" .

Si evalúa un array en contexto escalar, devuelve la longitud del array. (Tenga en cuenta que esto no es cierto para las listas, que devuelven el último valor, como el operador de coma C, ni para las funciones integradas, que devuelven lo que quieran devolver.) Lo siguiente es siempre cierto:

scalar(@whatever) == $#whatever + 1;

Algunos programadores optan por utilizar un conversión explícita para no dejar nada que dudar:

$element_count = scalar(@whatever);

Anteriormente en la misma sección se documenta cómo obtener el índice del último elemento de un array.

La longitud de un array es un valor escalar. Puede encontrar la longitud de la matriz @days evaluando $#days, como en csh. Sin embargo, esta no es la longitud de la matriz; es el subíndice del último elemento, que es un valor diferente ya que normalmente hay un elemento 0.

 2
Author: Greg Bacon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-03 15:48:11

Hay varias maneras de imprimir el tamaño de la matriz. Aquí están los significados de todos: Digamos que nuestra matriz es my @arr = (3,4);

Método 1: escalar

Esta es la forma correcta de obtener el tamaño de los arrays.

print scalar @arr;  # prints size, here 2

Método 2: Número índice

$#arr da el último índice de una matriz. así que si la matriz es de tamaño 10 entonces su último índice sería 9.

print $#arr;     # prints 1, as last index is 1
print $#arr + 1; # Add 1 to last index to get array size

Estamos agregando 1 aquí considerando la matriz como 0-indexada. Pero, si no se basa en cero entonces, esta lógica fail .

perl -le 'local $[ = 4; my @arr=(3,4); print $#arr + 1;'   # prints 6

El ejemplo anterior muestra 6, porque hemos establecido su índice inicial en 4. Ahora el índice sería 5 y 6, con los elementos 3 y 4 respectivamente.

Método 3:

Cuando se usa un array en contexto escalar, devuelve el tamaño del array

my $size = @arr;
print $size;   # prints size, here 2

En realidad el método 3 y el método 1 son iguales.

 2
Author: Kamal Nayan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-09 15:12:14

De perldoc perldata , que debería ser seguro citar:

Lo siguiente es siempre cierto:

scalar(@whatever) == $#whatever + 1;

Siempre y cuando no increase#lo que sea++ y misteriosamente aumentar el tamaño o su matriz.

Los índices del array comienzan con 0.

Y

Puede truncar un array a nada asignándole la lista nula (). Los siguientes son equivalentes:

    @whatever = ();
    $#whatever = -1;

Lo que me lleva a lo que estaba buscando que es cómo detectar la matriz está vacía. Lo encontré si empty # empty == -1;

 2
Author: jwal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-09 19:03:22

Para encontrar el tamaño de un array usa la palabra clave scalar:

print scalar @array;

Para encontrar el último índice de un array hay $# (variable por defecto de Perl). Da el último índice de una matriz. Como un array comienza desde 0, obtenemos el tamaño del array agregando uno a $#:

print "$#array+1";

Ejemplo:

my @a = qw(1 3 5);
print scalar @a, "\n";
print $#a+1, "\n";

Salida:

3

3
 0
Author: Sandeep_black,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-08 23:39:35

Qué pasa con int(@array) ya que amenaza el argumento como escalar.

 0
Author: Reflective,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-13 20:42:40