2016-10-18 10 views
0

私はPerlに助けが必要です。キーが呼び出されるたびに異なる値を出力する

私はIDのリストを持っています&ファイル内の対応する値。各IDはハッシュのハッシュでキーとして機能するため、各キーに複数の値があります。私は2番目のファイルを開こうとしています&キーに遭遇するたびに別の値を割り当てます。これは私がこれまで持っているものです:

このコードでは入力ファイル&がハッシュのハッシュを作成します。 $ protはキーです& $ dirは値です。各キーには複数の値があります。コードの第2部分において

open (IN, "file_name"); 
while (<IN>) 
{ 
($prot, $dir) = split; 
push (@{$dir{$prot}}, $dir); 
} 

、Iは、ファイルの各行を読みたい&キーとして行の最初の列を使用して別の値を割り当てます。それぞれのキーは、別の値を印刷したいと思うインスタンスごとに、2回目のファイル&に複数回表示されます。

open (FH, "results_file"); 
while (<FH>) 
{ 
chomp; 
@a=split; 
$prot=$a[1]; 
foreach (values %dir) 
{print "$a[1]"."\t"."@{$dir{$prot}}"."\n";} 
} 

現在、コードが書き込まれる方法は、キーに遭遇したときに各キーのすべての値を出力します。

ご協力いただきありがとうございます!

編集:

最初の入力ファイルが

BC_123456  dir_6789 
BC_456789  dir_3456 
BC_234689  dir_1298 
BC_123456  dir_3987 
BC_876432  dir_7642 
+0

あなたは、入力ファイルのサンプルを提供することはできますか? Data :: Dumperを使用する場合。 Dumper($ dir)を印刷します。あなたの最初の例の終わりに、期待どおりのデータ構造が見えますか? – mp3

+0

最初の入力ファイルのサンプルを追加しました。私が配列のハッシュに入れた後、データ構造は私が期待したように見えます。 – sapo42

+0

私はあなたが "異なる値を割り当てる"方法と苦労しています。あなたは「最初の列」と言っていますが、2番目の列を使用します(分割からの配列のインデックスはゼロベースです)。あなたのハッシュの配列に異なる値を割り当てたいですか?または印刷目的のために一時的に値を割り当てるだけですか? – mp3

答えて

0

ハッシュ

あなたが実際に持っているのハッシュでキーとして各IDの行為の線に沿って何かでありますそこの配列のハッシュ

、あなたが最初のインスタンスの最初の値を印刷したいと仮定すると、番目のインスタンスのための第二、というように、あなたはちょうどあなたが遭遇する各キーの値をオフシフトすることができます。

open (FH, "results_file"); 
while (<FH>) 
{ 
chomp; 
@a=split; 
$prot=$a[1]; 
    foreach (values %dir) { 
     my $val = shift @{$dir{$prot}}; 
     print "$a[1]\t$val\n"; 
    } 
} 

これは削除されます後でその配列を使用する必要がないと仮定して、HoAエントリから1つの値を取得します。

+0

まず、配列のハッシュとハッシュのハッシュを修正してくれてありがとう! :-)第二に、私はあなたの答えを試して&それは私がそれを印刷しようとすると$ valが初期化されていないことを伝え続けます。 – sapo42

+0

@ sapo42 $ valが戻って初期化されていない、次に来ている場合は、(1)そのハッシュ位置の配列がすでに空である、または(あなたのサンプルデータが正しいかどうかそう)(2)あなたは配列にはundef値をプッシュしていました。最初の入力ファイルからすべての値をすでに印刷した後に、どうなると思いますか? – harmic

0

これはあなたのコードが機能すると思います。注意すべきベストプラクティスがあります:

  • 警告は常に厳格な&警告の下で実行する必要があります。
    • use strict;
    • use warnings;
  • 私はエラーチェック(or die "message $!";)、およびファイルハンドルを格納するためのレキシカル変数で、open()の3つの引数バージョンをお勧めします。
    • 参照:
    • perldoc -f open
    • perldoc perlopentut
  • それらを使用して行われたときに、あなたのファイルを閉じます。
  • あなたが何か他のものを使用する正当な理由がない限り、変数はmyで(宣言)導入すべきです。

私もカップルは、私がお勧めしている間、彼らは必要ではないことに変更しました。

  • 変数@aが削除されました。実際には不要でした。
  • 読みにくかったので、あなたのprintをクリーンアップ。また、あなたは私が%dirs%dirの名前を変更して、私はこのケースでは混乱を見つけるDIR(01​​と$dir)という名前の2つのファイルを持っているprintf
  • を試みることができます。

CODE:

use strict; 
use warnings; 

my %dirs; 

# Part 1 - Input 
my $filename_input = "file_name.txt"; 
open(my $IN,'<',$filename_input) or die "Unable to open [$filename_input] for reading - $!"; 
while(<$IN>) { 
    my ($prot, $dir) = split; 
    push @{$dirs{$prot}}, $dir; 
} 
close $IN; 

# Part 2 - Output 
my $filename_results = "results_file.txt"; 
open(my $RESULTS,'<',$filename_results) or die "Unable to open [$filename_results] for reading - $!"; 
while(<$RESULTS>) { 
    chomp; 
    my $prot = (split)[1]; 
    foreach (values %dirs) { 
     print "$prot\[email protected]{$dirs{$prot}}\n"; # Or try: printf "%s\t%s\n",$prot,"@{$dirs{$prot}}"; 
    } 
} 
close $RESULTS; 

file_name.txt

BC_123456  dir_6789 
BC_456789  dir_3456 
BC_234689  dir_1298 
BC_123456  dir_3987 
BC_876432  dir_7642 

results_file.txt

don'tcare BC_123456 
don'tcare BC_234689 
関連する問題