Question

En Perl, le -1 d'index de tableau signifie que le dernier élément:

@F=(1,2,3);
print $F[-1]; # result: 3

Vous pouvez également utiliser la notation $# à la place, ici $#F:

@F=(1,2,3);
print $F[$#F]; # result: 3

Alors, pourquoi ne pas -1 et $#F donnent le même résultat quand je veux spécifier le dernier élément dans une plage:

print @F[1..$#F]; # 23
print @F[1..-1];  # <empty>

Le tableau @F[1..-1] devrait vraiment contenir tous les éléments de l'élément 1 à la dernière, non?

Était-ce utile?

La solution

Votre problème est la syntaxe @a[b..c] implique deux opérations distinctes. est évalué en premier b..c, retournant une liste, puis @a[] est évaluée avec cette liste. L'opérateur de gamme .. ne sait pas qu'il est utilisé pour les indices du tableau, donc dans la mesure où il est préoccupé, il n'y a rien entre 1 et -1. Elle retourne la liste vide, de sorte que le tableau renvoie une tranche vide.

Autres conseils

Il n'y a rien de spécial .. dans une tranche de tableau; il génère juste la plage demandée et la tranche de cette plage est recherchée.

@a[-3..-1] => @a[-3,-2,-1] et @a[1..3] => @a[1,2,3], mais @a[1..-1] devient @a[()].

print join ', ', 1..$#F; # 1, 2, 3, 4, 5, 6, ...
print join ', ', 1..-1;  #

La raison est que le « .. » opérateur n » t faire quelque chose de spécial à l'intérieur d'un indice de tableau.

  

Dans un contexte de liste, il renvoie une liste de valeurs de comptage (par les) de la valeur de gauche à la juste valeur. Si la valeur de gauche est supérieure à la valeur de droite, elle retourne la liste vide.


$#F est l'index du dernier élément, qui est la même que la longueur de moins d'une '@F -1. (Si la longueur est au moins un.)

$F[-1] est juste un cas particulier, pour le rendre plus facile d'obtenir à des éléments de l'autre extrémité, sans avoir à calculer la position manuellement.

$F[-1] === $F[ @F -1 ] === $F[ $#F ]

@F[ 1 .. (@F -1) ] === @F[ 1 .. $#F ]

@F[ 1 .. (@F -2) ] === @F[ 1 .. ( $#F -1 ) ]

Sachant cela, vous pouvez utiliser des variables dans un opérateur d'intervalle:

use strict;
use warnings;
use feature 'say';

sub list{
  my($arr,$first,$last) = @_;

  $first = @$arr + $first if $first < 0;
  $last  = @$arr + $last  if $last  < 0;

  return @$arr[ $first .. $last ];
}

my @F = 1..3;

say join ', ', list(\@F,1,-1)
2, 3

Note: Ceci est un exemple incomplet, il ne fonctionnera pas correctement pour certains cas limites

$ # F est le dernier indice valide de F, et non le nombre d'éléments.

@F = (1,2,3); # Donc $ # F est 2

Les règles sont les suivantes:

  • si l'index de matrice est non-négatif (ou, de manière équivalente, supérieure à $[), commencer à compter du début de la matrice
  • si elle est négative, commencez à compter à la fin
  • si on leur donne une gamme, retourner une tranche de tableau

Maintenant, tout comme l'ensemble (a, b) est vide si a> b , le 1 .. -1 set est également vide. Par conséquent,

@a[ empty set ]

correspond à une tranche de tableau vide.

L'opérateur [] acceptera soit un seul indice ou une plage.

-1 est acceptée comme index pour désigner l'indice de l'élément précédent. La bonne façon est $ # F.

Une gamme de 1 ..- 1 est vide, et qui est la raison pour laquelle il ne retourne rien, parce que l'évaluation de la gamme est distincte de l'évaluation de l'indice.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top