text---------------------
社会\t1
社会\t社会問題\t4
社会\t社会問題\t教育問題\t5
---------------------text
タブ区切りのテキストファイルを読み込んで
最後の値がハッシュ値になるような
深さがまちまちな多次元ハッシュをループで作りたいのです
手作業だと
$HASH{社会}=1
$HASH{社会}{社会問題}=4
$HASH{社会}{社会問題}{教育問題}=5
できるだけ動作を軽くしたいので、evalや$1での置き換え等は
使いたくないのです
どなたか教えてください
No.5ベストアンサー
- 回答日時:
>キー自体を使いたい(splitするコストがかかりますよね)
キー自体は、読み出す時にsplitするのだろうし、キーと値が切り出せれば別にsplitする必要もなく、'\t'を'/'にする必要もない(タブそのままでも良い)ですし、
ハッシュから値を読み出す時にも、キーが既に別々になっている状態で
$key1."/".$key2
のように連結すればいいだけのことで、
かえってテキストファイルによって動的に深さが決まるようなキーの場合、
%HASH{$key1}{$key2}…のような形で動的に深さを決定してアクセスするのが面倒です。
>いかんせん大量のデータ数&量を処理しようとしているので、なるべく軽くと思ってます
読み込みの部分が大量にあるとしても、それほど、重くなるとも思えません。
ハッシュからのアクセスの部分で言えば、かえって手順が簡単だと思います。
#3で指摘されているように、構造としてもうまく行かない場合があるようです。
#3でも言われているように、大量にデータがあるようなハッシュの場合、データの構造を変更して、DBに接続したハッシュにするのも1つの方法だと思います。
ありがとうございます
ご指摘のとおりに、構造の変更をしようと思います
本当は、初期のころちょっとだけその方法がよぎってました
じつは、複数DBの呼び出しのインデックス代わりに使おうと思っていたのです
で、最初はテキストを開いて ターゲットのDBファイルを読み込みに行こうと もくろんでました
いやー勉強になりました、やっぱり人の意見は役に立ちます
osayumさん・・おっとosamuyさんの指摘もあわせてとても有意義なやりとりでした
No.4
- 回答日時:
#1 です.
う~ん, ちょっとはチェックしたつもりだったんですけど, やっぱりそうなりましたか....
チェックの結果が奇妙だったんですがうまくいったように見えたので....
$hash{a}{b} って ${$hash{a}}{b} と同じだから当然といえば当然.
で,
while (@keys > 1) {
....
}
を
foreach my $key (@keys) {
$vref->{$key} = { };
$vref = $vref->{$key};
}
$vref->{val} = $val;
くらいでいいかと.
社会\t1
に対して
$hash{社会}{val} = 1
になりますけど, まあ許容範囲ではないでしょうか.
この回答への補足
追記ありがとうございます
確かにこれくらいが許容範囲ですね、しかもうまくいく!
ただ、
BLUEPIXYさん提案の方に傾きつつあります
ちょっとテストしてみましたが、10万くらいのデータだとさほど変わらないこと判明
さらに、人として読んだときにはBLUEPIXYさん提案のほうが手が入れやすいようでした
申し訳ない、趣旨変更しそうです
でも、ここまで付き合ってくれて感謝します
No.3
- 回答日時:
> $HASH{社会}=1
> $HASH{社会}{社会問題}=4
> $HASH{社会}{社会問題}{教育問題}=5
evalとかを使わないと記述が複雑になって、そんなに軽くならないし、メンテナンス性が悪くなるかと。
それと別に、こういうデータ構造だと、いくつか問題がありそう。
例えば、
$HASH{社会}=1;
$HASH{社会}{社会問題}=4;
$HASH{社会}{社会問題}{教育問題}=5;
$HASH{社会}{人生問題}=4;
$HASH{社会}{人生問題}{教育問題}=15;
print $HASH{社会}{社会問題}{教育問題};
??で、5と出力されません。
use strictを指定した場合、エラーになってしまいますし、リファレンスが生成されるため、通常のハッシュより遅くなります(微々たるものでしょうが)。
なので、BLUEPIXYさんみたいなやり方が適切と思われます。
タブ区切りテキストをやめてdbmにするという手も。
この回答への補足
あーほんとだ!(スイマセン)
確かに、うまくいかないですね
朝の5時までかかって考えぬき 出た答えがここに質問しょうでした 朦朧としていたのかもです
構造的なところは全然再検証していませんでした(最初のひらめきだけで進めていました)
ん~、かなり納得してます
指摘ありがとうございます、BLUEPIXYさんのやりかたにググッと傾いてきました
No.2
- 回答日時:
回答とは違うのですが、多重ハッシュにする理由がよくわかりません。
キーを{社会}{社会問題}{教育問題}とかしないで
社会/社会問題/教育問題とかすれば、
簡単だし軽いと思うのですが
#サンプル
my %HASH;
while (<>) {
chomp;
my (@keys) = split /\t/;
my $val = pop @keys;
print join('/', @keys) . "\n";
print "$val\n";
$HASH{join('/', @keys)}=$val
}
print $HASH{'社会'} . "\n";
print $HASH{'社会/社会問題'} . "\n";
print $HASH{'社会/社会問題/教育問題'} . "\n";
この回答への補足
助言(かな?)ありがとうございます
理由ですが、それなりに考えてのことなのですが・・
たとえば、
キー自体を使いたい(splitするコストがかかりますよね)
とか、他にもあるんですけど・・・
いかんせん大量のデータ数&量を処理しようとしているので、なるべく軽くと思ってます
簡単さは認めますが、あまり重要ではないんです
とりあえず使ったデータ(社会とか社会問題とか)が悪かったかもしれませんね
でも、BLUEPIXYさんに感謝!
No.1
- 回答日時:
こんな感じかなぁ?
my %HASH;
while (<>) {
chomp;
my (@keys) = split /\t/;
my $val = pop @keys;
my $vref = \%HASH;
while (@keys > 1) {
$vref->{$keys[0]} = {};
$vref = $vref->{shift @keys};
}
$vref->{$keys[0]} = $val;
}
この回答への補足
ありがとうございます さっそく試してみました
ちょっとやりにくいので、多少変更していますが趣旨は変わってないと思います
$array[0] = "社会\t1";
$array[1] = "社会\t社会問題\t4";
$array[2] = "社会\t社会問題\t教育問題\t5";
my %HASH;
for (@array) {
my (@keys) = split /\t/;
my $val = pop @keys;
my $vref = \%HASH;
while (@keys > 1) {
$vref->{$keys[0]} = {};
$vref = $vref->{shift @keys};
}
$vref->{$keys[0]} = $val;
}
print $HASH{'社会'} . "\n";
print $HASH{'社会'}{'社会問題'} . "\n";
print $HASH{'社会'}{'社会問題'}{'教育問題'} . "\n";
とすると、
HASH(0x1a99a38)
HASH(0x1ab8c64)
5
と出力され、どうもうまくいかないようです
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
perl 初等プログラミングについて
-
openした後、closeしないでプロ...
-
bashスクリプト
-
ターミナルで特定の文字と文字...
-
逆スラッシュを使わずにメタ文...
-
配列へのリファレンスへのリフ...
-
同一の検索値が複数存在する場...
-
Perl n列目の最小値 条件付き
-
Perl 仮登録、本登録システムに...
-
Perl 正規表現
-
Perl テキスト 重複 個数
-
Perl言語について。
-
Strawberry Perl for Windows ...
-
INDIRECT 横に再度抽出したい
-
テキストファイルで提出とは?
-
perl パターンマッチの前後の文...
-
PerlからPython3へ移行したい ...
-
Perl crypt パスワード 暗号化...
-
perl メール 一斉送信プログラム
-
Perlを使ったデータベースから...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
テキストファイルで提出とは?
-
INDIRECT 横に再度抽出したい
-
perlをバージョンアップしたら...
-
openした後、closeしないでプロ...
-
アルファベットに付いて質問し...
-
Strawberry Perl for Windows ...
-
bashスクリプト
-
Perlのエラーについてご教授く...
-
Perlで特定文字列から特定文字...
-
画像が表示でnull; this.src
-
Wallpaper Engineでおすすめの...
-
Perl言語について。
-
perl LWPでURLにアクセスした時...
-
Perlで時間の計算
-
Perlで、「が」を、「...
-
ファイルアイコンの左下に緑の□...
-
Perl の外部モジュールの利用方法
-
このファイルを開く方法で困っ...
-
perlで2次元配列をサブルーチ...
-
Windows10においての『Perl』の...
おすすめ情報