Perl将数组值与数组散列中的值进行比较

时间:2013-03-27 13:13:37

标签: arrays perl hash

此帖子已根据DVK的评论和回答进行了更新

我已经改为使用3参数形式的open和正确推送的ID到数组

更新以下代码

use warnings;
use strict;
use Data::Dumper;


my $file1 = "Inputfile.txt";
my $file2 = $ARGV[0];
my $file3 = $ARGV[1];

open (OF, " > Results.txt") or die "Can't write new file: $!";

my %hash;
open(INPUT1, "<" , $file1)or die("Failed to open file1: $!");
while (!eof(INPUT1)) {
    my @elements = split(/\t/, <INPUT1>);
    my $F1catagory = $elements[2];
    my $F1IDs = $elements[3];
    push @{$hash{$F1catagory}}, $F1IDs;
}
close(INPUT1);

my @array1;
open(INPUT2, "<" , $file2) or die ("Failed to open file2: $!");
while (!eof(INPUT2)) {
    my @line = split(/\t/, <INPUT2>);
    my $F2catagory = $line [0];
    my $F2IDs    = $line [1];
    push (@array1, $F2IDs);
}
print OF @array1;
close(INPUT2);

my @array2;
open(INPUT3, "<" , $file3) or die ("Failed to open file3: $!");
while (!eof(INPUT3)) {
    my @lines = split(/\t/, <INPUT3>);
    my $F3catagory     = $lines [0];
    my $F3IDs = $lines [1];
    push (@array2, $F3IDs );


}
print OF @array2;
close(INPUT3);

输入数据类似于

以下

文件1包含有关进程的信息,如下所示第3列包含进程ID,第4列包含项ID(这些用于创建我的%哈希)

process 9606    0051712 3458    [25 Jul 2011]
process 9606    0051712 2208    [25 Jul 2011]
process 9606    0051712 2150    [25 Jul 2011]
process 9606    0051712 4843    [25 Jul 2011]
process 9606    0032513 2280    [25 Jul 2011]
process 9606    0032513 2281    [25 Jul 2011]
process 9606    0006285 23583   [25 Jul 2011]
process 9606    0006285 6996    [25 Jul 2011]
process 9606    0006285 4913    [25 Jul 2011]
process 9606    0006285 10309   [25 Jul 2011]
process 9606    0006285 4350    [25 Jul 2011]
process 9606    0006285 4968    [25 Jul 2011]
process 9606    0006285 4595    [25 Jul 2011]
process 9606    0006285 8930    [25 Jul 2011]
process 9606    0051503 284439  [25 Jul 2011]
process 9606    0051503 2697    [25 Jul 2011]
process 9606    0051503 291 [25 Jul 2011]
process 9606    0051503 10478   [25 Jul 2011]

file2包含column1中项目的类别和第2列中的项目ID

CS1G2   1455
TM65    157378
PFN1    5216
HUL1    11100
ERI3    79033
PR12    57479
HIFN    55662
HNPD    3184
 HI2    28996
 LD1    84316
GRB2    2885
 AL6    84964
PCM1    5108
 ZN7    126208
MAK2    5605
BCL3    602

文件3与文件2相同,但项目ID不同

我需要查明文件1中的任何过程是否包含文件2和文件3中的项目。

我希望这会让问题更加清晰

#######原始问题

我在尝试编写的脚本上遇到了一些麻烦

我有一个包含进程信息的文件我已将进程ID和Item ID读入数组的哈希值,其中进程ID为键,Item ID为值(数组哈希为单个进程中的多个项)

我有两个Item ID数组 @ F2IDs和@ F3IDs

如果同一进程中的@ F2IDs和@ F3IDs中存在任何项目ID(在%hash的相同值中),我想识别它在同一进程中

到目前为止我有这个代码

use warnings;
use strict;
use Data::Dumper;

my $file1 = "Infile.txt";
my $file2 = $ARGV[0];
my $file3 = $ARGV[1];

open (OF, " > Results.txt") or die "Can't write new file: $!";


my %hash;
open(INPUT, $file1)or die("Failed to open file2");
while (!eof(INPUT)) {
    my @elements = split(/\t/, <INPUT>);
    my $F1catagory = $elements[2];
    my $F1IDs = $elements[3];
    push @{$hash{$catagory}}, $F1IDs;
}
close(INPUT);

open(INPUT, $file2) or die "Can't write new file: $!";
while (!eof(INPUT)) {
    my @line = split(/\t/, <INPUT>);
    my $F2catagory = $line [0];
    my @F2IDs    = $line [1];
}
close(INPUT);

open(INPUT, $file3) or die "Can't write new file: $!";
while (!eof(INPUT)) {
    my @lines = split(/\t/, <INPUT>);
    my @F3catagory     = $lines [0];
    my @F3IDs = $lines [1];
}
close(INPUT);    

我需要做类似下面的Pseudo代码,但不知道perl中是否存在“if in”构造,就像python中的那样

$insameprocess = False;
foreach value in %hash;
    if F2IDs and F3IDs are in {$hash{$catagory}};;
       $insameprocess = True;
       print OF "the key the value and if they are in the same process";

有任何人对如何在perl中执行此操作有任何想法吗?

提前感谢您的帮助 问候

取值

1 个答案:

答案 0 :(得分:0)

你有3个问题:

  1. 通常,您的脚本在读取数据时似乎包含许多错误。我暂时不会介绍,因为那不是你所问的。例如,您需要将ID推送到循环2/3中的数组中,而不是分配给数组(在第一个循环中正确执行)。

  2. 您的主要技术问题似乎是“如何判断哈希值中的某个ID(这是一个数组引用)?”。

    最好的方法是将数据存储在ID的hashref(映射到“1”)而不是ID的arrayref中,并使用哈希查找:

    # This is in your first loop reading file 1
    # OLD CODE:    push @{$hash{$catagory}}, $F1IDs;
    # NEW CODE:
    # # Each hash value is a hashref, with keys being IDsx and values simply 1
    $hash{$catagory}->{$F1IDs} = 1; 
    
    # This is the code in the end, to check if some ID is in the hash:
    if ($hash{$catagory}->{$F1IDs}) {
        # $id_is_in_hash = 1;
    }
    
  3. 坦率地说,你的伪代码对我来说没有多大意义(也不是你的描述)所以我无法帮助你编写一个完整的检查来替换你的伪代码使用我的解决方案从第2点开始。如果您可以提供更明确的描述,或者更好的示例数据包含3个文件和所需的输出,我将能够做更多。