WEB相談室

Webページ作成に関しての何でも掲示板です。

タイトル:perl 配列 → ハッシュ → 並びを変えて ハッシュ → 出力。

0:[投稿] くえ [2005/04/19 20:29 ][環境:わからない perl]

@ai = (1, 2, 3, 4, 5);
@as = ('a', 'b', 'c', 'd', 'e');
@at = ('1a', '2b', '3c', '4d', '5e');
上の配列を,

%ha = ('i' => \@ai, 's' => \@as, 't' => \@at);
と,ハッシュに入れてから,サブルーチンにリファレンスとして渡し,

サブルーチン内で,
%h1 = ('i' => 1, 's' => 'a', 'm' => '1a);
%h2 = ('i' => 2, 's' => 'b', 'm' => '2b');
%h3 = ('i' => 3, 's' => 'c', 'm' => '3c');
%h4 = ('i' => 4, 's' => 'd', 'm' => '4d');
%h5 = ('i' => 5, 's' => 'e', 'm' => '5e');
と,ハッシュにし,

1 a 1a
2 b 2b
3 c 3c
4 d 4d
5 e 5e
と,出力されるようにしたいです。
いろいろやってみましたが,方法が見つかりません。

最初の配列が増えたら,次のハッシュに入れる配列も増え,
サブルーチン内での処理も 例えば
1 a 1a 1ax
2 b 2b 2bx
……
9 i 9i 9ix
……
の様に増やせるものを作りたいと思っています。

よろしくお願いします。


1:[回答] B-Cus [2005/04/19 23:42 ]

こんな感じ。

@ai = (1, 2, 3, 4, 5);
@as = ('a', 'b', 'c', 'd', 'e');
@at = ('1a', '2b', '3c', '4d', '5e');
%ha = ('i' => \@ai, 's' => \@as, 't' => \@at);

$array_num = $#ai + 1;
while (($key, $ref_array)=each %ha){
  my @array = @$ref_array;
  for ( $i=0 ; $i<@array ; $i++ ){
     $hashname = sprintf("h%d", $i+1);
     $$hashname{$key}=$array[$i];
  }
}

foreach (sort keys %h1){ print "$h1{$_} " } print "\n";
foreach (sort keys %h2){ print "$h2{$_} " } print "\n";
foreach (sort keys %h3){ print "$h3{$_} " } print "\n";
foreach (sort keys %h4){ print "$h4{$_} " } print "\n";
foreach (sort keys %h5){ print "$h5{$_} " } print "\n";


シンボリックリファレンスを使わなければいけないため、このデータ構造は
いまいちです。

@ai・@as・@at をひとつのハッシュに突っ込む方がよいでしょう。


2:[回答] B-Cus [2005/04/19 23:43 ]

> $array_num = $#ai + 1;
は余計でした。


3:[回答] sim [2005/04/19 23:59 ]

したいことが良く判らないのですが・・・
こんなんですか?

@ai = (1, 2, 3, 4, 5);
@as = ('a', 'b', 'c', 'd', 'e');
@at = ('1a', '2b', '3c', '4d', '5e');

%ha = ('i' => \@ai, 's' => \@as, 't' => \@at);

&sample(\%ha);

sub sample{
    $ha = shift;

    for($i=0;$i < @{$ha->{'i'}};$i++){
        $key = $i + 1;
        $key = "h$key";
        foreach("i","s","m"){
            $$key{$_}[$i] = $ha->{$_}->[$i];
        }
    }

}


4:[回答] sim [2005/04/19 23:59 ]

あぁ。。書いてる途中に書き込みが・・
ごめんなさい。


5:[質問] くえ [2005/04/20 02:03 ]

B-Cusさま,simさま,ご回答ありがとうございます。

use strict;
してました……。
外したら,期待通りのものが帰ってきました。


> シンボリックリファレンスを使わなければいけないため、このデータ構造は
>いまいちです。
>
>@ai・@as・@at をひとつのハッシュに突っ込む方がよいでしょう。
これは,
>>@ai = (1, 2, 3, 4, 5);
>>@as = ('a', 'b', 'c', 'd', 'e');
>>@at = ('1a', '2b', '3c', '4d', '5e');
>>%ha = ('i' => \@ai, 's' => \@as, 't' => \@at);
ではなくて,

%ha = (
    'i' => 1, 'i' => 2, 'i' => 3, 'i' => 4, 'i' => 5,
    's' => 'a', 's' => 'b', 's' => 'c', 's' => 'd', 's' => 'e',
    't' => '1a', 't' => '2b', 't' => '3c', 't' => '4d', 't' => '5e'
);
が良い。という事でしょうか??

use strict;
している場合は,
>$hashname = sprintf("h%d", $i+1);
の部分からで,引っかかってしまうのでしょうか??

以下に,自分なりに試したものも書きます。
----------sub test
my $self = shift;
my $REC_hash = shift; #先に書いた \%ha を受け取ってます。

open(MAKE, '>./test.html');
seek(MAKE, 0, 0);

my $int;
while(my($key, $ref_array) = each %{$REC_hash}) {
    for($int = 0; $int <= $#${$ref_array}; $int++) {
        my $hash = sprintf("hash%d", $int);
        $hash->{$key} = $${$ref_array}[$int];
    };
};

for(my $integer = 0; $integer <= $int; $integer++) {
    my $hash = sprintf("hash%d", $integer);
    foreach my $key (keys %{$hash}){
        print MAKE $hash->{$key}, '<br />';
    };
};

truncate(MAKE, tell(MAKE));
close(MAKE);
chmod(0606, './test.html');


6:[お知らせ] くえ [2005/04/20 02:11 ]

上(#5)に書いたのは,4っつのパッケージを使っているために,他のパッケージからの部分を除いた,一部分です。

3っつのログファイルからの読み込みと,HTML ファイルを テンプレートにして,書き出しています。


7:[回答] B-Cus [2005/04/20 22:51 ]

> use strict;
http://perldoc.jp/docs/perl/5.8.1/strict.pod

> が良い。という事でしょうか??
同じキーを複数回使っても上書きされるだけでしょう。

わたしならまずは
 %ha = (
    'i'=>[1, 2, 3, 4, 5],
    's'=>['a', 'b', 'c', 'd', 'e'],
    't'=>['1a', '2b', '3c', '4d', '5e'],
 );

 @ha = (
    [1, 'a', '1a'],
    [2, 'b', '2b'],
    [3, 'c', '3c'],
    [4, 'd', '4d'],
    [5, 'e', '5e'],
 );

 @ha = (
    {'i'=>1, 's'=>'a', 't'=>'1a'},
    {'i'=>2, 's'=>'b', 't'=>'2b'},
    {'i'=>3, 's'=>'c', 't'=>'3c'},
    {'i'=>4, 's'=>'d', 't'=>'4d'},
    {'i'=>5, 's'=>'e', 't'=>'5e'},
 );

 @ha = (
    [1, 2, 3, 4, 5],
    ['a', 'b', 'c', 'd', 'e'],
    ['1a', '2b', '3c', '4d', '5e'],
 );
などのデータ構造を検討します。

シンボリックリファレンスが絶対ダメというわけではないので、
それなりの理由があるなら気にせず使えばよいでしょう。

> の部分からで,引っかかってしまうのでしょうか??
 $$hashname{$key}=$array[$i];

 $$key{$_}[$i] = $ha->{$_}->[$i];
のシンボリックリファレンスを使う部分で引っかかります。


8:[完了] くえ [2005/04/21 02:43 ]

B-Cusさま 度々ありがとうございます。

> 同じキーを複数回使っても上書きされるだけでしょう。
ですね。言われて気付きました。

実際には,
my $i = サブルーチンから配列で戻ってくるもの
my $s = 上に同じく(違うサブルーチン)
my $t = これも同じく配列で戻ってくるもの

my %h = ('i'=>\$i ……);
として また別のサブルーチンに渡しています。
このサブルーチンの中で,ハッシュの配列として使いたかったためですが,
動作を作っていた途中だったので,投稿時の様に書きました。

>  for($int = 0; $int <= $#${$ref_array}; $int++) {
>    my $hash = sprintf("hash%d", $int);
>    $hash->{$key} = $${$ref_array}[$int];
>  };
の部分は,
 for($int = 0; $int <= $#${$ref_array}; $int++) {
   $self->{'hash'}->{$int}->{$key} = $${$ref_array}[$int];
 };
としてみました。
一応,望みのものができました。

大変勉強になりました。
>>6
で,書いていただいたものなど,次に参考にしたいと思います。

回答(必須): 状態:

お名前(必須):

e-mail:

URL:




[戻る]

ChaichanPAPA's World