Perlで配列のサイズを見つける


243

配列のサイズを見つけるためにいくつかの異なる方法に出くわしたようです。これら3つの方法の違いは何ですか?

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

13
他の方法:print 0+@arrprint "".@arrprint ~~@arr
暴徒

3
@mob、ハムは、一つは避けたいかもしれない"".@arr"@arr"全く異なる何かをします。
池上2011

39
「2番目の方法」は配列サイズを出力する方法ではありません...
tadmc

スカラーコンテキストでは、; @ arrはテーブルサイズを返します。$ x = @ arrはスカラーコンテキストです。$#arrは配列の最後のインデックスを返します。インデックスは0から始まり、真の方程式$#arr + 1 == @arrです。$ arr [100] = 'any'のように順序に関係なく要素を書き込むと、テーブルは自動的に最大インデックス100まで(インデックス0を含めて)101要素まで増加します。
Znik

回答:


234

1番目と3番目の方法は同じです。スカラーコンテキストで配列を評価します。これは、配列のサイズを取得する標準的な方法だと思います。

2番目の方法は、実際には配列の最後のインデックスを返します。これは(通常)配列サイズとは異なります。


29
(1,2,3)のサイズが3であり、インデックスが(デフォルトで)0、1、2だからである、$#ARRは、この場合ではなく、3で2あろう
ネイトCK

5
事前定義された変数$[は、「配列の最初の要素と部分文字列の最初の文字のインデックス」を指定します(perldoc perlvar)。デフォルトでは0に設定されています。0以外に設定することはお勧めしません。
キース・トンプソン

5
@キース・トンプソン$[は落胆している(そして10年来ている)。$[廃止予定です。を使用$[すると、警告がオンになっていなくても非推奨の警告が発行されます。$[5.16では、ゼロ以外を割り当てるとエラーになります。$[すでに言及するのをやめることはできますか?
池上2011

2
@キース・トンプソン、5.14より古い、実際。しかし、私が言ったように、それはずっとそれよりずっと長い間落胆して非難されました、そして使用している誰か$[はその影響を知っています。
池上2011

7
@ikegami:はい、誰かの違いを理解しようとするscalar @arr$#arrする必要があり、まだ効果の可能性を理解し$[、彼らはあるけれども稀に、。
キーストンプソン

41

まず、2番目は他の2つと同等ではありません。$#array配列のサイズより1つ小さい配列の最後のインデックスを返します。

他の2つは実質的に同じです。単に2つの異なる手段を使用してスカラーコンテキストを作成しています。それは読みやすさの問題に帰着します。

私は個人的に以下を好みます:

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

私はそれがより明確であると思います

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

そして

my $size = @array;
say $size;

後者はこのように単独で非常に明確に見えますが、他のコードの一部である場合、余分な行が明確さから離れていることがわかります。これ@arrayは、スカラーコンテキストで何を行うかを教える場合や、$size複数回使用する場合に便利です。


15
個人的には、「スカラー」キーワードを使用するバージョンを好みます。これは、スカラーコンテキストを強制していることが非常に明確であるためです。my $size=@array間違った印章が使用されたのは間違いかもしれません。
ネイトCK

5
それは本当に悪い考えです。scalar理由もなく使う人は間違った教訓を学びます。彼らは、オペレーターがスカラーに強制変換できるリストを返すことに頭を悩ませ始めています。何十回も見ました。
池上2014

2
これはなぜ「理由がない」のですか?scalarリストをスカラーコンテキストに強制するために使用しています。それがそれを使う正しい理由です。あなたの例はまったく同じことを行いますが、暗黙的にスカラーコンテキストでリスト変数を評価するときにPerlが何をするかに依存します。したがって、あなたの例では、読者がそのコンテキストでのPerlの暗黙の動作について知る必要があります。暗黙の動作のもう1つの層を式に追加するだけで、Perlにはすでにプログラムの解読のために推論しなければならない暗黙の動作が多すぎます。
Nate CK

2
@Nate CK、Re「これはなぜ「理由がない」のですか?scalarリストをスカラーコンテキストに強制しているので、あなたは使用しています」、あなたは間違ったレッスンを学ぶことについて私のポイントを証明しています。これは完全に誤りです。によって強制されるリストはありませんscalar。(それがなかった、場合scalar(@array)scalar(@array[0..$#array])同じものを返します。)scalar(@array)伝え@arrayすでにで行うには、それを告げたスカラを返すようにmy $size=
池上2014

2
信じられないかもしれませんが、開発者は他の開発者が作成したコードをデバッグする必要があります。また、開発者は3年前に作成したコードをデバッグする必要があります。
Nate CK

27

これは、配列をスカラーコンテキストに強制することによってサイズを取得し、そのサイズとして評価されます。

print scalar @arr;

これはスカラー変数に割り当てられているため、配列をスカラーコンテキストに強制する別の方法です。

my $arrSize = @arr;

これは配列の最後の要素のインデックスを取得するので、実際にはサイズから1を引いたものになります(インデックスが0から始まると仮定します。これはPerlで調整可能ですが、そうすることは通常悪い考えです)。

print $#arr;

この最後の1つは、配列サイズを取得するために使用するのにはあまり適していません。配列の最後の要素を取得するだけの場合に便利です。

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

また、ここでStack Overflowを見るとわかるように、この構文はほとんどの構文ハイライターで正しく処理されていません...


2
補足:$arr[-1]最後の要素を取得するためだけに使用します。そして$arr[-2]、最後から2番目のものを取得します。
tuomassalo 2015

1
@tuomassalo:あなたの提案がより良いアプローチであることに同意します。振り返ってみると、$#arrはあまり便利な機能ではありません。他の言語にこの機能がないのは偶然ではありません。
Nate CK

6

2番目の方法を使用するには、1を追加します。

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

for [0..$#array] { print $array[$_ ] } ただし、要素の数を取得する目的が配列を反復処理することである場合は、うまく機能します。利点は、整列された要素とカウンターを取得することです。
Westrock、2016

5

2つ目を少し変更しても、3つすべてで同じ結果が得られます。

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
これは、この回答とこの回答ですでに言及されているものとは異なりますか?
devnull 2013年

5

例:

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

warn "Size: " . $#a;   # Size: 1. It's not the size
warn "Size: " . $size; # Size: 2

2

「Perlの変数タイプ」セクションperlintroドキュメントが含まれています

特殊変数$#arrayは、配列の最後の要素のインデックスを示します。

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

$#array + 1配列内のアイテムの数を通知するのに使いたくなるかもしれません。気にしないでください。たまたま、@arrayPerlがスカラー値を見つけると予想される場所(「スカラーコンテキスト内」)を使用すると、配列内の要素の数がわかります。

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

perldataドキュメントはまた、これをカバーし、「スカラー値」セクション

スカラーコンテキストで配列を評価すると、配列の長さが返されます。(これは、Cのコンマ演算子のような最後の値を返すリストや、返そうと思うものを返す組み込み関数には当てはまらないことに注意してください。)以下は常に当てはまります。

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

一部のプログラマは、疑いの余地がないように明示的な変換を使用することを選択します。

$element_count = scalar(@whatever);

同じセクションの前半では、配列の最後の要素のインデックスを取得する方法について説明しています。

配列の長さはスカラー値です。のように@days評価すると$#days、配列の長さがわかりますcsh。ただし、これは配列の長さではありません。これは最後の要素の添え字であり、通常は0番目の要素があるため、値は異なります。


2

配列のサイズを出力するにはさまざまな方法があります。すべての意味は次のとおりです。配列がmy @arr = (3,4);

方法1:スカラー

これは、配列のサイズを取得する正しい方法です。

print scalar @arr;  # prints size, here 2

方法2:インデックス番号

$#arr配列の最後のインデックスを与えます。したがって、配列のサイズが10の場合、最後のインデックスは9になります。

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

ここでは、配列を0インデックスと見なして1を追加しています。しかし、それがゼロベースでない場合、このロジックは失敗します。

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

上記の例では、初期インデックスを4に設定しているため、6が出力されます。インデックスは5と6になり、要素はそれぞれ3と4になります。

方法3:

配列がスカラーコンテキストで使用される場合、配列のサイズを返します

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

実際、方法3と方法1は同じです。


2

安全に引用できるperldoc perldataから:

以下は常に当てはまります。

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

$#whatever ++を行わずに、不思議なことにサイズまたは配列を増やしてください。

配列のインデックスは0から始まります。

そして

配列にnullリスト()を割り当てることにより、配列を何もない状態に切り詰めることができます。以下は同等です。

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

これにより、配列が空であることを検出する方法である、私が探していたものが表示されます。$#empty == -1の場合、それを見つけました。


1

int(@array)それがスカラーとしての議論を脅かすときはどうですか?


0

配列のサイズを調べるには、次のscalarキーワードを使用します。

print scalar @array;

配列の最後のインデックスを見つけるために$#(Perlのデフォルト変数)があります。配列の最後のインデックスを提供します。配列が0から始まるので、配列に1を追加してサイズを取得します$#

print "$#array+1";

例:

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

出力:

3

3
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.