28

最後のIDではなく、配列内のアイテムの総数を取得するにはどうすればよいですか?

私がこれを行うために見つけた2つの方法のどれもうまくいきません:

my @a;
# Add some elements (no consecutive ids)
$a[0]= '1';
$a[5]= '2';
$a[23]= '3';

print $#a, "\n"; # Prints 23
print scalar(@a), "\n"; # Prints 24

私は3を得ると期待していました...

4

6 に答える 6

40

編集:ハッシュと配列

cincodenadaがコメントで正しく指摘しているように、ysthはより良い答えを出しました。「本当にPerl配列を使用したいですか?ハッシュの方が適切かもしれません」という別の質問であなたの質問に答えるべきでした。

配列は、これまでに使用された最大のインデックスまでのすべての可能なインデックスにメモリを割り当てます。この例では、24個のセルを割り当てます(ただし、3個のみを使用します)。対照的に、ハッシュは実際に使用されるフィールドにのみスペースを割り当てます。

配列ソリューション:スカラーgrep

考えられる解決策は次の2つです(説明については以下を参照)。

print scalar(grep {defined $_} @a), "\n";  # prints 3
print scalar(grep $_, @a), "\n";            # prints 3

説明:を追加した後$a[23]、配列には実際には24個の要素が含まれていますが、それらのほとんどは未定義です(これもfalseと評価されます)。定義された要素の数(最初のソリューションで行われたように)または真の要素の数(2番目のソリューション)を数えることができます。

違いはなんですか?を設定$a[10]=0すると、最初のソリューションはそれをカウントしますが、2番目のソリューションはカウントしません(0は偽であるが定義されているため)。を設定する$a[3]=undefと、どのソリューションもそれをカウントしません。

ハッシュソリューション(ystによる)

別の解決策で提案されているように、ハッシュを使用してすべての問題を回避できます。

$a{0}  = 1;
$a{5}  = 2;
$a{23} = 3;
print scalar(keys %a), "\n";  # prints 3

このソリューションは、ゼロとundef値をカウントします。

于 2009-05-14T14:03:05.940 に答える
16

スパース配列が必要なようです。通常の配列には24個のアイテムが含まれますが、スパース配列には3個のアイテムが含まれます。Perlでは、スパース配列をハッシュでエミュレートします。

#!/usr/bin/perl

use strict;
use warnings;

my %sparse;

@sparse{0, 5, 23} = (1 .. 3);

print "there are ", scalar keys %sparse, " items in the sparse array\n",
    map { "\t$sparse{$_}\n" } sort { $a <=> $b } keys %sparse;

keysスカラーコンテキストの関数は、スパース配列内のアイテムの数を返します。ハッシュを使用してスパース配列をエミュレートすることの唯一の欠点は、キーの順序が重要な場合は、キーを反復処理する前にキーを並べ替える必要があることです。

また、この関数を使用してスパース配列からアイテムを削除することも忘れないでくださいdelete(値をundefに設定するだけでは不十分です)。

于 2009-05-14T14:09:14.833 に答える
14

代わりに(またはさらに)ハッシュが必要な場合があります。配列は順序付けられた要素のセットです。を作成する場合は、を介し$foo[23]て暗黙的に作成します。$foo[0]$foo[22]

于 2009-05-14T14:00:11.157 に答える
8
print scalar grep { defined $_ } @a;
于 2009-05-14T13:53:39.020 に答える
1
@people = qw( bob john linda ); 
$n = @people; # The number 3
Print " The number in the list is $n \n"; 

Perlの式は、常にコンテキストに適した値を返します。

たとえば、配列の「名前」*はどうですか?リストコンテキストでは、要素のリストを提供します。ただし、スカラーコンテキストでは、配列内の要素の数を返します。

于 2013-12-28T16:03:46.680 に答える
0
sub uniq {
    return keys %{{ map { $_ => 1 } @_ }};
}
my @my_array = ("a","a","b","b","c");
#print join(" ", @my_array), "\n";
my $a = join(" ", uniq(@my_array));
my @b = split(/ /,$a);
my $count = $#b;
于 2012-03-19T10:06:23.937 に答える