每次调用密钥时都打印不同的值

时间:2016-10-18 02:03:46

标签: perl hash

我需要Perl帮助。

我有一份ID列表&文件中的相应值。每个ID都充当哈希散列中的键,因此每个键都有多个值。我正在尝试打开第二个文件&每次遇到密钥时分配不同的值。以下是我到目前为止的情况:

此代码采用输入文件&构建哈希的哈希值。 $ prot是关键& $ dir是值。每个键都有多个值。

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

在代码的第二部分,我想阅读文件的每一行&amp;使用行中的第一列作为键指定不同的值。每个密钥将在第二个文件中多次出现&amp;对于每个实例,我希望它打印一个不同的值。

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

2 个答案:

答案 0 :(得分: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)

我认为这会让您的代码正常运行。有一些最佳实践需要注意:

  • 你应该总是在严格的&amp;警告。
    • use strict;
    • use warnings;
  • 我推荐open()的三个参数版本,带有错误检查(or die "message $!";),以及用于存储文件句柄的词法变量。
    • 参见:
    • perldoc -f open
    • perldoc perlopentut
  • 完成后使用它们关闭文件。
  • 除非您有充分理由使用其他内容,否则应使用my引入(声明)变量。

我也做了一些改变,虽然我建议,但他们没有必要。

  • 删除了变量@a,因为您实际上并不需要它。
  • 清理你的print,因为它很难阅读。您也可以尝试printf
  • 您有两个名为dir(%dir$dir)的文件,在这种情况下我感到困惑,所以我将%dir重命名为%dirs

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\t@{$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