@list=(20,25,24,32,28,20,28,24,20);
という、ある組織の人間の年齢の配列を定義したとします。
そこで、
foreach $fld(@list){
$syukei{$fld}++;
}
というforeach文によって、年齢を「キー」として集計していくという説明を受けたのですが、いきなりスカラー変数の$syukeiが出てきて、さっぱりわかりません。
$syukei{$fld}++;
という一行の意味を教えてくださらないでしょうか。
また、++という記号を使用していますが、これを別の書き方で書き換えることはできないでしょうか。
No.5ベストアンサー
- 回答日時:
> その場合なんですが、%syukeiの使用宣言というのは、
> 何をすればいいのでしょうか。
とりあえず、↓かな。
%syukei = ();
これは「宣言」というほどのものではありません。
単なる「初期化」です。
しかも Perl が自動的にやってくれていることを、改めて書いています。
一見ムダのようですが、人が「プログラムを読む」ときに、これは宣言と同等の意味を持ちます。
たとえば、後にコードをメンテナンスしたり、他の人と共有することになったときに、これがないと1からコードを解読するハメになったりします(苦笑)。
さらに用途をコメントしておくなどすると、よりよいでしょう。
# 人数カウント用ハッシュ(キー:年齢、値:人数)
%syukei = ();
また、より高度な話になってしまいますが、こんな宣言方法もあります。
my %syukei;
これは「変数のローカライズ」というもので、変数を限定された場所だけで利用する場合の「宣言」です。(上記の単なる初期化とは異なります。)
これを理解するには、まず「変数のスコープ」についての理解が必要なので、後の課題とされるとよいかと思います。
大きなスクリプトを書く時には必要にもなってきますが、今は特に気にしなくてもよいでしょう。
ありがとうございます。
初期化の方法、大変よくわかりました。
たしかに人のコードを読む際には、
他人がみてもよくわかるようなコードに仕上げる必要はありますよね。
まだまだ未熟ですが、perlの面白さにはまりつつあります。
がんばります。
ご丁寧にありがとうございました。
No.4
- 回答日時:
「ハッシュ(連想配列)」というのはご存知ですか?
これは配列と同様に、1つの変数内にいくつもの値を格納できるタイプの変数です。
配列は @var で表し、$var[ 添字 ] という形式で各要素にアクセスしますよね。
添字は0から始まる正の整数値で、このため要素の並びが保持され、データを順次処理するのに向きます。
ハッシュは %var と表し、$var{ 添字 } という形式で各要素にアクセスします。
添字は「キー」と呼ばれる「文字列」であるため、配列とは異なり要素の並びが保持されません。
問題の
$syukei{$fld}++;
は、暗黙のうちに %syukei というハッシュ変数を用意し、キーが $fld である要素の値をインクリメントしています。
(本当はループ前に %syukei の使用宣言をした方がよいです。)
各要素の初期値は「未定義値(数値としては 0)」なので、上記スクリプトでは「年齢ごとの人数」をカウントしていることになります。
ハッシュの各要素を取り出すには、keys 関数を使うのが一般的です。
keys はハッシュの全てのキーをリストにして返します。
foreach $key (keys %var) {
print "$key => $var{$key}\n";
}
keys が返すキーの並びは内部的なものなので、これを年齢(数値)順にしたいときは sort 関数を使って次のようにします。
foreach $key (sort {$a <=> $b} keys %var) {
print "$key => $var{$key}\n";
}
※詳しくは sort 関数について調べてみてください。
回答ありがとうございます。
やっと意味がわかりました。
最初は各要素の初期値は未定義値なんですね。
それでゼロがあり、
また、最初に
%syukeiとして、宣言しておいたほうがよいということですね。
その場合なんですが、%syukeiの使用宣言というのは、
何をすればいいのでしょうか。
ハッシュについては、まだ勉強を始めたばかりで、
配列のほうがイメージしやすかっただけに、
キーという概念を捉えるのが非常に困難を極めておりました。
ですが、すこし光がさしてきたように思えます。
No.3
- 回答日時:
連想配列というのは、キーがユニークな値なんですね。
ですから、
@list=(20,25,24,32,28,20,28,24,20);
を
foreach $fld(@list){
$syukei{$fld}++;
}
で、連想配列に格納していくと以下のような結果になります。
$syukei{'20'} = 3;
$syukei{'24'} = 2;
$syukei{'25'} = 1;
$syukei{'28'} = 2;
$syukei{'32'} = 1;
ソースの最後に以下を追加してみてください。
while ( ($key,$val) = each(%syukei) ) {
print "$key=$val\n";
}
連想配列の仕組みが分かると思いますよ。
ちなみに連想配列の値は何も数値でなくても構いません。
上記ソースの%syukeiを%ENVにすると環境変数が出力されます。
参考になれば幸いです。
ありがとうございました。
ソースの最後に教えてくださった一文を加えて、
ブラウザで確認をしてみました。
連想配列とは非常に難しいというか、慣れるまでは、使いにくいですね。
でも、おかげさまで、今はしんどいですが、
もうしばらくがんばればなんとかなりそうな気もしてきました。
ご丁寧にありがとうございました。
No.2
- 回答日時:
$syukei{$fld}++;
は連想配列と呼ばれるものです。
$syukeiという変数のキーに$fldが入ります。
ここでは値に++として数値を1ずつプラスしています。
@listの内容から集計結果は例えば、
$syukei{'20'} = 3;
となります。
@listの配列に20が3つありますよね。
ちなみに連想配列は%で現します。
この例では、%syukeiに連想配列が格納されます。
ありがとうございます。
回答を何度も読ませていただきましたが、
まだ理解に苦しんでいます。
>$syukeiという変数のキーに$fldが入ります。
とのことですが、となると、まず、一番先頭の
20が入るということですよね。
それに、++していくのですから、
20が21になるような気がするのですが、
これは違うとは思うのですが、説明ができない状態です。
foreach文は繰り返し処理をする命令文なので、
なぜ、++を毎度してあげるのかということもわからなくなってしまいました。
一番最初の年齢の「20」というのは、初期値がゼロで、初めて出てきた段階で、++により、ゼロから1にカウントされるのでしょうか?
ちぐはぐな文章になってしまいましたが、もう一度アドバイスいただけないでしょうか。
宜しくお願いします。
No.1
- 回答日時:
$syukei(集計)という変数は、おそらく年齢が現れる頻度を格納するものでしょう。
foreach ループで配列 @list の要素を順に見ていって、
20歳だったら $shukey{20} の値が一つ増えると。
>++という記号を使用していますが、これを別の書き方で
>書き換えることはできないでしょうか。
$syukei{$fld} = $syukei{$fld} + 1;
と同じ意味ですが、長くなるので誰もこのような書き方はしませんね。
ありがとうございます。
nightowlさんのおっしゃられるとおりで、
年齢が現れる頻度が格納されるようです。
ですので、20歳は3つとなります。
実は、何度も回答を読み直したのですが、
まだ理解できないんです。
まず、いきなり$syukeiというスカラー変数が出てくるのであれば、
$syukei=
という形で入るべきではないかと思うのですが、
どうもわかりません。
また$syukei{$fld}で、$syukei{20}の場合、
$syukei{$fld}++だと、20,21,22と増えていくのではないのでしょうか?それは違うとわかっているつもりなんですが、説明しろと言われると、自分ではどういえばいいのかわからない状態です。
頭の中がぐちゃぐちゃになってしまいました。
$syukei{$fld}=$syukei{$fld}+1;
と書き換えられるという意味は理解致しました。
foreachの文章の中に、
++という演算子を用いるということがイメージしにくくて困っています。
もう一度アドバイスお願いできますでしょうか。
宜しくお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- PHP PHPでCSVを出力するさいに、ループの中で前の行の値を変更したい 3 2022/10/27 17:44
- PHP PHPでCSVを出力するさいに、ループの中で前の行の値を変更したい 1 2022/10/27 14:21
- PHP PHPの構文で間違えが分からない 5 2022/07/11 16:38
- PHP SQLとPHPの連結方法がわからないのでアドバイスお願い致します 1 2022/07/12 12:16
- PHP 配列の値の更新方法について 1 2022/08/05 09:49
- PHP アコーディオンPHPが上手くいかない 3 2022/07/15 16:29
- PHP ファイルの書き込みについて教えて下さい。 1 2023/03/20 12:01
- PHP style.cssのjQuery条件付きcssが機能しない 4 2022/07/17 18:27
- Excel(エクセル) フォルダ内のワードファイルをPDFに一括変換するVBA 3 2023/06/09 16:51
- JavaScript console.logがどうしても2つ機能しないのでアドバイスをくださいお願いします 2 2022/07/07 22:13
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
GETメソッドとPOSTメソ...
-
ポインター引数の関数でコンパ...
-
10Mバイトて文字数に すると何...
-
ESC/Pのテキスト印字の制...
-
Rstudioによるテキストマイニン...
-
メールフォームで改行スペース...
-
VB6で漢字の1バイト目か2バイト...
-
CGIを勉強しています。¥n(改...
-
Excel 1セル当りの文字数が2...
-
メールの件名をデコードしたい
-
cgiでの文字化け
-
Excel VBA メール作成について ...
-
int型(2バイト)データの分割
-
sedコマンドで全ての2バイト文...
-
matlabでのRRI検出
-
char str[256]の256の意味は?
-
ログイン後のソースの取得
-
【VB】文字列を50バイトづつに...
-
perlのgrepでmyを付けた場合と...
-
MATLAB(マトラボ)とcsvファ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
POSTメソッドの最大容量について
-
GETメソッドとPOSTメソ...
-
perlのCGIのハッシュを使った、...
-
CGIの変数に配列を代入する方法
-
VBAでプロシージャ間のデータを...
-
ポインター引数の関数でコンパ...
-
10Mバイトて文字数に すると何...
-
UTF-8で5~6バイトになる文字コ...
-
char str[256]の256の意味は?
-
エクセルシート名の制限を変更...
-
DataGridViewの特定列に入力さ...
-
COBOLのCOMP形式について
-
「1TB」のHDDに日本語は何字入...
-
Excel VBA メール作成について ...
-
stable diffusionのエラー
-
Excel 1セル当りの文字数が2...
-
バイナリとBCDコード
-
ビットスワップとバイトスワッ...
-
ピクセル,dpiから容量(バイト...
-
バイト列とバイナリ列の違いが...
おすすめ情報