大きなプログラムを組む(3)
2021/05/09
表のデータを扱ってみる
  • 前回レポートでは、Perlでデータの構造化を行うために必要な参照(リファレンス)について話をしました。今回は具体例を通して理解を進めたいと思います。まずは例として下記時刻表のようなデータがあるとしましょう。

  • Table 1: 時刻表データ


  • このデータを見たまま下記のように書きたくなるところですが、これだと全て結合されて1個のリストになってしまいます。
    # 下記は1個のリストになり、2次元としての情報は失われれる
    my @time_table = (
      ('北千住', '08:00', '08:10', '08:20', '08:30', '08:40'),
      ('綾瀬',  '08:03', '08:13', '08:23', '08:33', '08:43'),
      ...
    );

  • 前回、関数への引数にリファレンスを使いましたが、今回も独立としたいリストは参照で渡します。表記は下記となります。
    my @time_table = (
      ['北千住', '08:00', '08:10', '08:20', '08:30', '08:40'], # リストのリファレンス[0]
      ['綾瀬',  '08:03', '08:13', '08:23', '08:33', '08:43'], # リストのリファレンス[1]
      ...
    );

  • あれ? 丸括弧"(...)"が角括弧"[...]"になっただけ? のようの感じられたと思いますが、その通りです。角括弧"[...]"はリストのリファレンスを意味します。
    my @list_obj = ('data0', 'data1', ...); # list_objというリスト
    my $list_ref = ['data0', 'data1', ...]; # 無名(anonymous)リストのリファレンス

  • ついでなので、ハッシュのリファレンスも覚えましょう。波括弧"{...}"はハッシュのリファレンス(*1)を意味します。
    my @hash_obj = ('key0'=>'val0','key1'=>'val1',...); # hash_objというハッシュ
    my $hash_ref = {'key0'=>'val0','key1'=>'val1',...}; # 無名(anonymous)ハッシュのリファレンス

データにアクセスする
  • データへのアクセス方法ですが、値そのものにアクセスするにはデリファレンスする必要があります。例えば、'綾瀬'の2番目のデータ'08:13'に相当するデータへアクセスするには、下記にように書きます。
    print ${$time_table[1]}[2],"\n";
     ・リストのリファレンスである$time_table[1]をデリファレンスし
     ・その要素[2]を指している

  • わかりにくい...とてもわかりくいですね。しかし心配ご無用。Perlにはデリファレンスを容易にするためアロー演算子'->'が用意されており、普通はこれを使ってアクセスします。
    print $time_table[1]->[2],"\n"; # こちらの方がわかりやすいですね

  • そして前回レポートの冒頭で書きましたが、Perlのリストとハッシュは動的にメモリ確保を行うので、下記のように最初からリファレンスを経由した値の設定ができます。
    my @time_table = (); # とりあえず空リストを定義
    $time_table[0]->[0] = '北千住';
    $time_table[0]->[1] = '08:00';
    ...
    $time_table[1]->[0] = '綾瀬';
    $time_table[1]->[1] = '08:03';
    ...

  • コードの中に値を直接埋めると一見面倒ですが、スクリプトを作るケースでデータを手入力したり、コードに直接埋め込むことは少なく、多くのケースは外部ファイルからの読み込みです。結果としてデータアクセスにはアロー演算子を多用することになります。

  • リスト内部の無名リストも動的に確保できてしまうわけですが、ならば起点のリストもリファレンスから始められそうですね。はい。起点部もリファレンスにできます
    my $time_table; # リファレンスを受けるための変数定義
    $time_table->[0]->[0] = '北千住'; # $time_table自身にもアロー演算子適用
    $time_table->[0]->[1] = '08:00';
    ...
    $time_table->[1]->[0] = '綾瀬';
    $time_table->[1]->[1] = '08:03';
    ...

次回は
  • リファレンスとアロー演算子を利用することで、構造化されたデータの構成とアクセスは比較的簡単にできると感じていただけたでしょうか。

  • 次回はリファレンスの続きになりますが「どうして、いきなりリファレンスで書けるんだっけ?」といった理由の説明などをしたいと思います。
Notes
  • '{'のことを「波括弧」と呼ぶことを初めて知りました。「中括弧」は今風じゃないらしいです...
Copyright(C) 2021 Altmo
本HPについて