Parece que he encontrado 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
print 0+@arr
,print "".@arr
,print ~~@arr
"".@arr
igual"@arr"
que algo muy diferente.Respuestas:
La primera y la tercera forma son las mismas: evalúan una matriz en contexto escalar. Consideraría que esta es la forma estándar de obtener el tamaño de una matriz.
La segunda forma en realidad devuelve el último índice de la matriz, que no es (generalmente) el mismo que el tamaño de la matriz.
fuente
$[
especifica "El índice del primer elemento en una matriz y del primer carácter en una subcadena" (perldoc perlvar
). Se establece en 0 de forma predeterminada, y se desaconseja configurarlo en algo que no sea 0.$[
está desanimado (y lo ha estado durante una década).$[
es obsoleto. El uso$[
emite una advertencia de desaprobación incluso cuando no se activan las advertencias. Asignar cualquier cosa menos cero a$[
será un error en 5.16. ¿Podemos dejar de mencionarlo$[
ya?$[
sabría sus efectos.scalar @arr
y aún$#arr
debe entender los posibles efectos de , aunque sean raros.$[
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 iguales. Simplemente está utilizando dos medios diferentes para crear un contexto escalar. Se trata de una cuestión de legibilidad.
Personalmente prefiero lo siguiente:
Lo encuentro más claro que
y
Este último parece bastante claro solo así, pero encuentro que la línea adicional 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.fuente
my $size=@array
parece que podría ser un error donde se usó el sigilo incorrecto.scalar
sin razón aprenden la lección equivocada. Empiezan a pensar que los operadores devuelven listas que pueden convertirse en escalares. Visto decenas de veces.scalar
porque está obligando a la lista a un contexto escalar. Esa es la razón correcta para usarlo. Su ejemplo hace exactamente lo mismo, pero se basa en lo que hace Perl cuando evalúa una variable de lista en un contexto implícitamente escalar. Por lo tanto, su ejemplo requiere que el lector sepa sobre el comportamiento implícito de Perl en ese contexto. Solo está agregando una capa más de comportamiento implícito a la expresión, y Perl ya tiene demasiado comportamiento implícito que debe razonar para descifrar un programa.scalar
porque estás obligando a la lista a un contexto escalar", has demostrado mi punto sobre aprender la lección incorrecta. Esto es completamente falso. Ninguna lista es obligada porscalar
. (Si lo hiciera,scalar(@array)
yscalar(@array[0..$#array])
devolvería lo mismo.) Lescalar(@array)
dice@array
que devuelva un escalar, que ya le dijo que hicieramy $size=
.Esto obtiene el tamaño al forzar la matriz a un contexto escalar, en el que se evalúa como su tamaño:
Esta es otra forma de forzar la matriz a un contexto escalar, ya que se está asignando a una variable escalar:
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 es generalmente una mala idea):
Este último no es realmente bueno para usar para obtener el tamaño de la matriz. Sería útil si solo desea obtener el último elemento de la matriz:
Además, como puede ver aquí en Stack Overflow, esta construcción no se maneja correctamente por la mayoría de los resaltadores de sintaxis ...
fuente
$arr[-1]
para obtener el último elemento. Y$arr[-2]
para obtener el penúltimo, y así sucesivamente.$#arr
no es una característica muy útil, y no es casualidad que otros idiomas no la tengan.Para usar la segunda forma, agregue 1:
fuente
for [0..$#array] { print $array[$_ ] }
Sin embargo, funciona muy bien si el propósito de obtener el número de elementos es iterar a través de la matriz. La ventaja es que obtienes el elemento y un contador que están alineados.Los tres dan el mismo resultado si modificamos un poco el segundo:
fuente
Ejemplo:
fuente
La sección "Tipos de variables de Perl" de la documentación de Perlintro contiene
La documentación de Perldata también cubre esto en la sección "Valores escalares" .
Anteriormente en la misma sección se documenta cómo obtener el índice del último elemento de una matriz.
fuente
Hay varias formas 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 las matrices.
Método 2: número de índice
$#arr
da el último índice de una matriz. entonces, si la matriz es de tamaño 10, entonces su último índice sería 9.Estamos agregando 1 aquí considerando la matriz como 0 indexada . Pero, si no está basado en cero, entonces, esta lógica fallará .
El ejemplo anterior imprime 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 utiliza una matriz en contexto escalar, devuelve el tamaño de la matriz.
En realidad, el método 3 y el método 1 son iguales.
fuente
De perldoc perldata , que debería ser seguro citar:
Siempre y cuando no $ $ lo que sea ++ y aumente misteriosamente el tamaño o su matriz.
y
Lo que me lleva a lo que estaba buscando, que es cómo detectar que la matriz está vacía. Lo encontré si $ # empty == -1;
fuente
¿Qué pasa
int(@array)
ya que amenaza el argumento como escalar?fuente
Para encontrar el tamaño de una matriz, use la
scalar
palabra clave:Para averiguar el último índice de una matriz existe
$#
(variable predeterminada de Perl). Da el último índice de una matriz. Como una matriz comienza desde 0, obtenemos el tamaño de la matriz agregando uno a$#
:Ejemplo:
Salida:
fuente