4

Perlでは、配列インデックス-1は最後の要素を意味します。

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

$#代わりに、ここで表記を使用することもできます$#F

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

それで、範囲の最後の要素を指定したいのに、なぜ同じ結果-1を出さないのですか?$#F

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

配列に@F[1..-1]は、要素から1最後の要素までのすべての要素が実際に含まれている必要がありますね。

4

6 に答える 6

19

あなたの問題は、@a[b..c]構文に2つの異なる操作が含まれていることです。最初b..cに が評価されてリストが返され、次に@a[]そのリストで評価されます。範囲演算子..は、それが配列の添字に使用されていることを認識していないため、1 と -1 の間には何もありません。空のリストを返すため、配列は空のスライスを返します。

于 2009-07-19T16:08:17.440 に答える
8

配列スライスの .. について特別なことは何もありません。要求された範囲を生成するだけで、その範囲のスライスが検索されます。

したがって@a[-3..-1]=> @a[-3,-2,-1]、および@a[1..3]=>@a[1,2,3]ですが、 に@a[1..-1]なり@a[()]ます。

于 2009-07-19T16:10:34.003 に答える
5
print join ', ', 1..$#F; # 1, 2, 3, 4, 5, 6, ...
print join ', ', 1..-1;  #

この理由は、' ..'演算子が配列添字内で特別なことを何もしないためです。

リスト コンテキストでは、左の値から右の値まで (1 ずつ) カウントする値のリストを返します。左の値が右の値より大きい場合、空のリストを返します。


$#Fは最後の要素のインデックスで、長さから ' ' を引いたものと同じ@F -1です。( 長さが 1 つ以上の場合。)

$F[-1]位置を手動で計算しなくても、反対側から要素を取得しやすくするための特殊なケースです。

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

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

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

これを知っていれば、範囲演算子で変数を使用できます。

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

注: これは不完全な例です。一部のエッジ ケースでは正しく機能しません。

于 2009-07-19T16:50:12.897 に答える
4

$#F は、要素の数ではなく、F の最後の有効なインデックスです。

@F = (1,2,3); # なので $#F は 2 です

于 2009-07-19T16:32:05.147 に答える
2

ルールは次のとおりです。

  • 配列インデックスが負でない (または同等に より大きい$[) 場合、配列の先頭からカウントを開始します。
  • 負の場合は、最後からカウントを開始します
  • 範囲が与えられた場合、配列スライスを返します

ここで、集合(a,b)がa > bの場合に空であるように、集合1 .. -1も空です。したがって、

@a[ empty set ]

空の配列スライスに対応します。

于 2009-07-19T21:51:02.727 に答える
0

[] 演算子は、単一のインデックスまたは範囲のいずれかを受け入れます。

-1 は、最後の要素のインデックスを意味するインデックスとして受け入れられます。正しい方法は $#F です。

1..-1 の範囲は空です。そのため、範囲の評価はインデックスの評価とは別であるため、何も返されません。

于 2009-07-19T16:08:14.993 に答える