• ベストアンサー

レコードセットを配列のハッシュ形式で返すメソッド

DBI.pmのメソッドで、 selectall_arrayref()は配列の配列形式、 selectall_hashref()はハッシュのハッシュ形式でレコードセットを返しますが、 配列のハッシュ形式で返すメソッドは存在するのでしょうか。 ハッシュのキーは列名として、 ハッシュの値はORDER BY句で指定したとおりに整列された配列へのリファレンスとなるような、ハッシュを生成しようとしています

  • Perl
  • 回答数2
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

my $arrayref = $dbh->selectall_arrayref('select * from user_info', {Slice => +{}}); print Dumper($arrayref); --- $VAR1 = [      {       'name' => 'Alice',       'id' => '1'      },      {       'name' => 'Bob',       'id' => '2'      }     ];

zyousuke
質問者

お礼

こんにちは! なんとselectall_arrayref()でハッシュの配列を受け取ることができたのですね。 selectall_arrayref()の柔軟な用法を知らずに格好悪い質問をしてしまいました。 selectall_arrayref()の第二引数に戻り値の形式を指定できるのですね! ハッシュの配列がほしいときは{Slice => {}}とするのですね。 このとき{}ではなく+{}とすると、どうなるか試してみたのですが違いは分かりませんでした。 {}の前に+を付けるとどうなるのでしょうか??? また便利な関数Data::Dumper()を覚えました(^_^)b

その他の回答 (1)

回答No.2

> このとき{}ではなく+{}とすると、どうなるか試してみたのですが違いは分かりませんでした。 > {}の前に+を付けるとどうなるのでしょうか??? +{}と書くとハッシュリファレンスであると明示できます。 数は多くないですが、{}がハッシュリファレンスなのか、そうでないのか曖昧になることがあります。他人が書いたコードを見てビックリしないぐらいには理解したほうがよいでしょう。 use strict; use warnings; use Data::Dumper; use feature 'say'; sub proto_func ($) { say 'proto_func($)'; } proto_func {say 'hoge'}; # Odd number of elements in anonymous hash at foo.pl line 11. proto_func +{a => 1}; sub hashref_ambiguous { {@_} } # return {@_} sub hashref_strict { +{@_} } # return +{@_} my $ambiguous = hashref_ambiguous( 'a', 'b' ); my $strict = hashref_strict( 'a', 'b' ); print Dumper($ambiguous); # $VAR1 = 2; print Dumper($strict); # $VAR1 = { #      'a' => 'b' #     };

zyousuke
質問者

お礼

{}や+{}はselectall_arrayref()の引数専用の書き方ではなくPerl全体としての書き方だったのですね。 {}は空ハッシュ、+{}は空ハッシュへのリファレンスを意味していたのですね。 ご紹介のコードは+の有無によって違いが発生する例ですね。 このコードを解読するのもいささか時間がかかりました^^; 新しく覚えたワードはfeatureプラグマ、say関数です。 しかしながら配列の各要素はスカラー値と決まっているのでselectall_arrayref()の第二引数に書くときは+を省略して{}と書けるといったところでしょうか。

関連するQ&A

  • メソッドが返す型を調べるにはどうしたらよいのでしょうか?

    メソッドが返す型(配列、スカラー、ハッシュ、リファレンスなど)を調べるにはどうしたらよいのでしょうか? どなたかご存じの型教えていただけると嬉しいです _ _

    • ベストアンサー
    • Perl
  • ハッシュについて教えて下さい

    現在出来るだけ高速に大量の英単語の登録(検索)を行いたいと考えています。 現在は受け付ける文字の種類を進数にして桁上げして、クローズドで(最初にがっぽり配列を用意してその中のどこかに入れる形式で)計算しています。 例えば0~9の文字のみ受け付ける仕様だとすると、文字の種類は10種類なので、「192」という文字列なら、 1*10^2 + 9*10^1 + 2*10^0 = 192番地に登録 といった感じです。今回大小アルファベットを含むので10→62で計算しています。 しかしこの方法では、62進数が膨大な数になるため、配列に上限があることから、完全なユニークな数値が生成出来ません。 ある程度ハッシュ値がぶつかってしまいます。 完全にユニークな数値は無理でしょうが、出来るだけ衝突は避けたいと考えています。 そこで、もっと効率よいハッシュ値を求めるMurMurHash 2.0というアルゴリズムを聞いたのですが、HPを見ても何が何だかよくわかりません; HPにてMurmurHash2.cppが公開されているので、もしご存知の方がいらっしゃればそのアルゴリズムを教えていただけないでしょうか。 http://www.google.co.jp/search?hl=ja&rlz=1C1GGLS_jaJP302JP303&q=MurMurHash+2.0&btnG また、高速な文字列登録(検索)を行う為の方法があれば教えて下さい。 よろしくお願いいたします。

  • Perlで変数内の日本語が文字コードに変換される

    お世話になります。Googleやbingなどで調べて見ましたが検討もつかず困っております。 PerlでDBIを使用し、データベースのテーブルAに対してSelectした場合に、fetchrow_hashrefを使用しSelect結果を取得した場合に、テーブルの列名が文字ではなく文字コードが格納されてしまいます。 テーブルAの列名はUTF-8の日本語文字になります。 以下、列名 ID|登録者|登録日 fetchrow_hashrefを使用した場合、以下のように返ってきます。 $VAR1 = { "\x{767b}\x{9332}\x{8005}" => '106.190.xxx.xxx', "\x{767b}\x{9332}\x{65e5}" => '2012-05-06 00:52:40.39496', 'id' => 38 }; 問題は目的のデータに対して列名('登録日'など)で参照する事が出来ない事ですが、今のままテーブルの列名は日本語のままで回避する方法をご教授いただけないでしょうか? hashrefを使いたい理由はテーブルの列順番が変わった場合でもプログラム上の変更を減らすために、列名にて参照したいためです。ですのでarray系の取得メソッドはなるべく使わないようにしたいです。 出来ればなぜこのようなことが起こるのか原因も含めてご教授いただけると大変助かります。。 ちなみに、データベースはPostgreSQLの8.2で日本語文字に対応していることは、自分でselectなどのコマンドを叩き確認済みです。 ヒントでもかまいませんので、どうかよろしくお願いいたします。

    • ベストアンサー
    • Perl
  • Perlで一覧表示

    お世話になっております。 Perl初心者で、Java等は少し経験があります。 「検索を行い一覧を表示する」という画面をPerlで作成する際の 作り方について質問させてください。 現在は以下のような構成で画面を作っています。(DBアクセスには DBI を使用しています) ------------------------------ 【DAO的な pm】  引数として検索条件を受け取り、  DB にアクセスし、  $sth->fetchrow_arrayref で取り出した検索結果を  ハッシュや配列に詰めて返す 【画面の pl】 上記DAO的な pm を利用して検索結果を受け取り、 それをループで回して一覧として表示する ------------------------------ ただ、これだと配列にデータをため込むので 検索結果が多くなるとメモリをくいそうで気になっています。 (あと後述の方法と比べるとやっぱり遅い気がする…) 他の方が Perl で作った画面を見たところ、以下のような作り方を見かけました。 ------------------------------ 【画面の pl】 画面内で SQL を発行し、 $sth->fetchrow_arrayref で取り出した検索結果を 逐次出力していく ------------------------------ こちらのほうだと、一覧に出すものが多くても 上からパラパラ表示されていくので 閲覧者側のストレスも少ないと思ったのですが、 Perlの作りとしてはこういうほうが一般的なのでしょうか。 なんとなくDBアクセスは汎用的なクラスにしてしまいたい気持ちになるのですが Perlではあんまりそういうことはしない、とかPerlでもするよ、とか ご存じの方がいらっしゃいましたら教えてください。 あとは関数の戻り値として検索結果をごそっと返すのではなくて、 関数の引数として「一件分のデータを受け取るDelegate」を渡してみたらどうだろうかとか思っているのですが 変でしょうか… よろしくお願いします。

  • 1つのキーに複数の値があるハッシュ(連想配列)をcsvに出力する

    表形式のデータにおいて、列数が行によって可変長となる場合のエレガントな方法を探しています。 ■やりたいこと csv形式の元データを1行可変列に変換し、excelに読み込ませる。 excelに読み込ませるデータをrubyで処理したい。 処理前のデータ  コード、属性ともにユニークではない  コードは数値型、属性は文字型  コード 人数1 人数2  属性  1    1    100   A    2    1    0    B  3    4    1    A  2    5    8    C  4    1    122   D 処理後の最終形態  コードは重複なし。  コード  属性  1     A  2     B,C  3     A  4     D この処理を  元のデータを1行ずつ読み出す  ハッシュに追加する  ハッシュをcsvに書き出す と考えて、下記のようなコードを書きましたが、属性部分がカンマで区切られず、配列の値がすべて連結されてしまいます。 ■質問 こういうデータを処理するときにどうすればいいか? (後学のために、なぜそうしたほうがよいのかを教えていただけると幸いです) 具体的にこのコードを書き直すとしたら、どこをどう変更すればよいか? いろいろなリファレンスを読んだのですが、列数が可変長となる場合のサンプルが見つけられなくて詰まってしまいました。 よろしくお願いいたします。 環境:active ruby 1.8.6 , windows XP SP3 , ■作成したコード(抜粋) require 'csv' in_path='C:\Documents and Settings\a\デスクトップ\解凍後データ\dummy.txt' out_path='C:\Documents and Settings\a\デスクトップ\解凍後データ\out.txt' #set initial values col_code=0 'コード列位置 col_zokusei=3 '属性列位置 h=Hash.new{|h,key| h[key]=[]} CSV.foreach(in_path){|row| h[row[col_code]]<<row[col_zokusei] } #put hash to csv file. CSV.generate(out_path){ |writer| h.to_a.each{ |row| p row writer << row } }

    • ベストアンサー
    • Ruby
  • 最終配列にNULLが含まれる場合の対応について

    下記のソースで テキスト入出力を行う際でのご質問がございます。 最終配列がNULLの時と 文字がある場合のデータを入出力する際に Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1 at ExIO3.getValue(テスト.java:53) at ExIO3.main(テスト.java:14) というエラーが表示されます。 最終配列にすべて文字が存在する場合は問題ないのですが こちらはBufferedReaderで 1レコードずつ読み込んでいるソースに問題があるのでしょうか? アドバイスどうぞよろしくお願いします。 import java.io.*; //(1)入出力パッケージのインポート import java.text.Normalizer; class ExIO3 { //mainメソッド public static void main(String[] args) throws IOException { ExIO3 object1 = new ExIO3(); //(1)抜出しメソッドgetValueと、 // ソートメソッドsortValueの呼出 object1.sortValue(object1.getValue()); } //getValueメソッド Reader getValue () throws IOException { //(2)FileReaderオブジェクトcsvの生成 FileReader csv = new FileReader ("C:\\javasample\\テスト\\src\\テストin.txt"); //(3)BufferedReaderクラスでFileReaderクラスの // オブジェクトcsvをラップ BufferedReader in = new BufferedReader(csv); //(4)PipedWriterオブジェクトpipeOutを生成 PipedWriter pipeOut = new PipedWriter(); //(5)PipedReaderオブジェクトpipeInを生成 PipedReader pipeIn = new PipedReader(pipeOut); //(6)PrintWriterクラスでPipedWriterクラスの // オブジェクトpipeOutをラップ PrintWriter out = new PrintWriter("C:\\javasample\\テスト\\src\\テストout.txt"); //************************************************************************************************ //(7)入力テキストデータ //************************************************************************************************ String line; String[] arrayline; Integer sequence_No =0 ; //行のカウンタ //(8)読み込みソースがなくなるまでBufferedReaderで1行ずつ読み込み、 // 読み込みデータをprintlnメソッドで書き込み while((line = in.readLine()) != null) { sequence_No++; //連続番号生成 arrayline = line.split(","); //====================================================== String A= arrayline[0] ; String B = arrayline[1] ; //====================================================== //************************************************************************************************ //(9)出力テキストデータ //************************************************************************************************ 顧客郵便番号_編集(A,out); out.print(","); // ※ 顧客住所_編集(B,out); out.println(""); // ※ out.flush(); } //(10)読み込みストリームのクローズ in.close(); //(11)書き込みストリームのクローズ out.close(); return pipeIn; //(12)pipeInオブジェクトのリターン } //************************************************************************************************ //顧客郵便番号_編集A1 //************************************************************************************************ private void 顧客郵便番号_編集(String a, PrintWriter out) { // TODO 自動生成されたメソッド・スタブ out.print(a.replaceAll(" ","").replaceAll(" ","")); } //************************************************************************************************ //顧客住所_編集B2 //************************************************************************************************ private void 顧客住所_編集(String b, PrintWriter out) { // TODO 自動生成されたメソッド・スタブ out.print(b); } //sortValueメソッド void sortValue(Reader source) throws IOException { } }

    • ベストアンサー
    • Java
  • ハッシュの配列を作ることは可能でしょうか?

    次のようなファイルがある場合、%hash1と%hash2を同じ配列として扱いたいと思っています。 例えば、hash[0]{A}とアクセスすれば'01'、hash[1]{B}とアクセスすれば'002'となるようにしたいと思っています。ご教授ください。 -------------------- A B C 01 001 0001 02 002 0002 %hash1 = {'A'=>'01', 'B'=>'001', 'C'=>'0001'}; %hash2 = {'A'=>'02', 'B'=>'002', 'C'=>'0002'};

    • ベストアンサー
    • Perl
  • ハッシュの配列???

    基本的なことなのですが、 @data{qw(aaa bbb ccc)} と書くとどのようなデータ構造になるでしょうか? 要素に値を代入するにはどのように書けばいいでしょうか?

    • ベストアンサー
    • Perl
  • Access レコードセットを動的配列に

    初めて質問させていただきます。Access勉強中です。 Access VBA 2007 でテーブルのデータを取得した動的配列から、構造体定義した動的配列に入れたいのですが、コンパイルエラーが発生してしまいます。 ネットで調べたのですがわからずじまいで、ここで相談させていただいています。 やりたいことは、テーブルの内容全てを動的配列に入れたい、それだけです。 やり方には固執していませんので、よろしくお願いします。 [コンパイルエラー] パブリック オブジェクト モジュールで定義されたユーザー定義型に限り、変数に割り当てることができ、実行時バインディングの関数に渡すことができます。 [実際のプログラム]Form内のボタン押下時に実行される Private Sub btn_Click() Dim db As DAO.Database Dim rst As DAO.Recordset Dim varRecords As Variant Dim intRecCnt As Integer Set db = CurrentDb() Set rst = db.OpenRecordset(テーブル名称, dbOpenSnapshot) rst.MoveLast: rst.MoveFirst intRecCnt = rst.RecordCount varRecords = rst.GetRows(intRecCnt) Dim COutRec() As Record '行ループ For intRLoop = 0 To UBound(varRecords, 2) ReDim Preserve COutRec(intRLoop) '列方向(フィールド)のループ For intCLoop = 0 To UBound(varRecords, 1) '配列の各データを配列にセット COutRec(intRLoop, intCLoop) = varRecords(intCLoop, intRLoop) Next intCLoop Next intRLoop End Sub [構造体定義]標準モジュール内に定義している Type Record A As String B As String End Type

  • intra-martの自動生成DAO

    intra-martを勉強中です。 eBuilder7.2を使用してDAOを自動性すると下記の問題が発生します。 回避方法をご存知でしたらご教示ください。 1)取得レコードが1件のSELECTメソッドを作成した場合  生成ソースのresultSet取得部分が数字の指定になる。  これをカラム名指定にしたい。  result.setEmpCd(resultSet.getString(1));  ->  result.setEmpCd(resultSet.getString("EMP_ID")); 2)取得レコードが複数件(配列)のSELECTメソッドを作成した場合  生成ソースのresultSet取得部分が  ダブルクォーテーション囲みの数字の指定になる。  当然"1"というカラムはないためException発生。  これをカラム名指定にしたい。  result.setEmpCd(resultSet.getString("1"));  ->  result.setEmpCd(resultSet.getString("EMP_ID"));

    • ベストアンサー
    • Java

専門家に質問してみよう