ハッシュのeach関数を使って「猫はcat犬はdogお茶tea」と表示させるプログラムの主要部分です。
%list = ("猫"=>"cat" , "犬"=>"dog" , "お茶"=>"tea");
while( ($key,$val) = each( %list ) ){
print "$keyは$val";
}
whileの条件部分の意味が分かりません。
・なんで条件部分なのに代入みたいな式が入るのか?
・$keyと$valというのは普通のスカラー変数とは違うのか?
良く分からないので質問の仕方もおぼつかないですが、どなたか分かりやすく説明して頂けないでしょうか?
No.2ベストアンサー
- 回答日時:
はいはい、補足です(笑)
>each(%list) が返すのは (猫,cat) という
その通りです。
「猫」と「cat」がそれぞれ配列変数の値として入ります。
>print each(%list); と書く
print 文における配列の扱いは例外で、「中身をセパレータなしで並べて表示する」という動きをします。(セパレータを入れたい場合はシステム変数に設定)
ですのでこの場合、print 文は、each(%list) が返した('猫','cat')という配列の中身を、セパレータなしでつなげて「猫cat」と表示したわけです。
>この中にある、$list{$key} という部分ですが
はい、その通りです。
まず関数 keys は、ハッシュ配列変数のキー名すべてを配列にして返す関数です。
foreach は、その「返された配列」を1つ1つ $key に入れてループしてくれます。
すると、最初のループでは $key には '猫' が入ることになるわけですから、$list{$key} は $list{'猫'} と同じ意味になります。
もちろん、次のループでは $key には '犬' が入るわけです。
ですので、このプログラムと最初の質問のプログラムは同じ事をすることになります。
丁寧にお答えくださって有り難うございます。
う~ん、しかし分かったような分からないような・・
一度にたくさんのことを詰め込もうとし過ぎているのか、まだ混乱しています。
これから何度も読み直してみます。
No.1
- 回答日時:
C言語もそうなんですが、Perl の条件式の特徴は、「比較と代入を同時に行える」という点です。
そのために、比較演算子(==)と代入演算子(=)が別になってるんです。このとき、比較式を記述しなければならない場所(今回の場合は while の中)に代入式だけを記述すると、Perl は自動的に、「代入された値が真か偽か」によって判定を行います。
真とは、0以外の数値や、undefine、または null ではない文字など、何かを処理するのに適した値です。
逆に偽とは、0、undefine、null です。
each は、ファイルの読み込みと同じようにハッシュ変数の中身を、呼び出すごとに順番に「配列として」返す変数で、すべての配列を呼び出し終わると null を返します。
ですので、正常なデータが返されているうちは、while はそれを「真」であると解釈し処理を繰り返しますが、each が null を返すと、すべての処理が終わったのだと解釈し、ループを抜けるわけです。
それから、($key, $val) という記述ですが、こんな記述ができるのは、俺が知る中では Perl だけです。(マイナーな言語には他にもこれができるものがあるようですが)
Perl の関数が「配列」という巨大なデータを返すとき、それを受け取るための手法の1つがこの書き方です。
通常は配列を返す関数に関しては、受け取り側も配列を記述するのが普通です。
@kv = each( %list );
この書き方をすれば、$kv[0]、$kv[1] にそれぞれ値が入りますが、これでは少し面倒です。
そこで、Perl では、($key, $value) という括弧そのものを、「1つの仮的な配列」として扱うことができるのです。
ですのでこの処理が終わってしまえば、$key も $value もそれぞれスカラー変数として扱えます。
これを利用すれば、
($a, $b) = ($b, $a);
という記述も出来ます。これは、$a と $b の中身を入れ替えるという処理です。
説明が長くなってしまったので、不明点は別途補足ください(^_^;
この回答への補足
補足というか追加質問になってしまうのですが、次のような例文がありました。
foreach $key(keys(%list)){
$val = $list{$key};
print "$keyは$val";
}
この中にある、$list{$key} という部分ですが、これはハッシュの要素へのアクセスを示す $ハッシュ名{'キー名'} でしょうか?
ありがとうございます!条件が真か偽で判断することを忘れていたのと、リスト書式で代入が出来るということを知らなかったのが原因でした。
しかしそうすると each(%list) が返すのは (猫,cat) という書式のものと考えて正解ですか?しかし、 print each(%list); と書くと表示されるのは「猫cat」というようにキーと値がそのまま横に並んだものです。
なんかイマイチ納得できないです・・
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 大学・短大 C言語線形リストの問題です 3 2022/12/22 00:45
- その他(プログラミング・Web制作) pythonにおける単方向リストの実装について 4 2022/07/13 12:34
- Java Java 南京錠 2 2023/02/04 11:46
- Visual Basic(VBA) ExcelVBAで、index、match関数を使用して、指定範囲に出力したい 3 2022/10/18 21:53
- C言語・C++・C# 至急教えてください。プログラミングの問題です。 malloc関数を使ってください!お願いします! 最 1 2022/07/21 09:28
- Ruby プログラミング 3 2023/06/09 14:30
- C言語・C++・C# 至急教えてください。プログラミングの問題です。 最初に正の整数nの入力を受け付け、次に分数の分子と分 1 2022/07/19 17:03
- C言語・C++・C# 至急お願いします。プログラミングの問題です。 最初に正の整数nの入力を受け付け、次に分数の分子と分母 3 2022/07/19 17:09
- 統計学 機械学習(最適化問題)のプログラムで、以下の2つの関数がどんな関数なのかご存知の方はおりますか? d 5 2022/06/23 00:35
- その他(データベース) Microsoft Accessについて 1 2022/06/06 16:20
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
二次元配列のインデックスについて
-
VBAのautofilter、criteriaの配...
-
配列を初期化する時ってどうす...
-
perlで配列の要素が空なのを知...
-
DataGridViewに配列の値を表示...
-
csv形式のデータの一部を削除し...
-
ファイル名に日付・時刻を付与...
-
マクロ Publicでの配列定義
-
隣同士の数字を足し合わせる
-
エクセルVBAでTransposeの不思議
-
Perlで<select multiple>の複数...
-
VB6で配列の最大値を簡単に求め...
-
jcode->jfold で禁則処理
-
N88互換BASICで「メッセージの...
-
画面を強制的に再描画させる方法
-
VBAでの一時停止と再開の方法
-
Escキーを押すと、中断する時と...
-
VBAで3秒だけ時間を止めたい
-
Javaでゲーム
-
ハッシュ検索はなぜ速い
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
二次元配列のインデックスについて
-
VBAのautofilter、criteriaの配...
-
Excel VBA ユーザーフォームの...
-
二次元配列における要素数のは...
-
マクロ Publicでの配列定義
-
Strawberry Perl for Windows ...
-
リストボックスに縦スクロール...
-
クラスに配列を渡す方法
-
Dim flag(4) as boolean で配列...
-
エクセルVBAでTransposeの不思議
-
perlで2次元配列をサブルーチ...
-
perlで配列の要素が空なのを知...
-
perl 配列の要素数について
-
組み合わせについての質問です...
-
隣同士の数字を足し合わせる
-
複数の配列の全ての組み合わせ...
-
perl 初等プログラミングについて
-
jcode->jfold で禁則処理
-
一致する要素が格納されている...
-
チェックボックスのperlでの値...
おすすめ情報