2016-10-08 2 views
-1

Хотя мой код работает без возникновения фатальной ошибки, результат явно ошибочен. Сначала создаю хэш массивов. Затем я просматриваю последовательности в файле против ключей в хэше. Если последовательность существует как ключ в хеше, я печатаю ключ и связанные значения. Это должно быть достаточно простым, и я правильно создаю хэш массивов. Однако, когда я печатаю связанные значения, я получаю «ARRAY (0x7ff4bbb0c7b8)» на своем месте.Ошибка ARRAY (0x7ff4bbb0c7b8): perl hash массивов

Файл "INFILE" ТАВ delimitated и выглядит, как это, например:

AAAAA  AAAAA 
BBBBB  BBBBB  BBBBB 

Вот мой код:

use strict; 
use warnings; 

open(INFILE, '<', '/path/to/file') or die $!; 
my $count = 0; 

my %hash = ( 
    AAAAA => [ "QWERT", "YUIOP" ], 
    BBBBB => [ "ASDFG", "HJKL", "ZXCVB" ], 
); 

while (my $line = <INFILE>){ 
    chomp $line; 
    my $hash; 
    my @elements = split "\t", $line; 
    my $number = grep exists $hash{$_}, @elements; 
    open my $out, '>', "/path/out/Cluster__Number$._$number.txt" or die $!; 
    foreach my $sequence(@elements){ 
     if (exists ($hash{$sequence})){ 
      print $out ">$sequence\n$hash{$sequence}\n"; 
     } 
     else 
     { 
      $count++; 
      print "Key Doesn't Exist ", $count, "\n"; 
     } 
    } 
} 

Выходной ток выглядит следующим образом:

>AAAAA 
ARRAY(0x7fc52a805ce8) 
>AAAAA 
ARRAY(0x7fc52a805ce8) 

Ожидаемый результат будет выглядеть так:

>AAAAA 
QWERT 
>AAAAA 
YUIOP 

Большое спасибо за помощь.

+0

'@ {$ hash {$ sequence}} ' – melpomene

ответ

1

Ключевым моментом здесь является работа с ссылкой на массив, принадлежащих хэша, а не просто пытаясь распечатать его. Независимо от того, что вы захотите удалить первый элемент из массива, вы можете сделать это с помощью функции shift. Затем вы можете либо push элемент в конце массива, либо delete ключ от хэша, когда больше нет элементов в зависимости от того, что вы хотите, когда все ключи были использованы один раз. Вы можете также выбрать случайный элемент из массива с rand функции, как это:

my $out_seq = $hash{$sequence}[rand [email protected]{ $hash{$sequence} }]; 

Если вы хотите пунктов выбежать в случайном случае, вы должны удалить элемент из массива. Лучший способ сделать это, вероятно, с splice (родовой форме shift, unshift, pop и push):

my $out_seq = splice @{ $hash{$sequence} }, rand @{ $hash{$sequence} }, 1; 
delete $hash{$sequence} unless @{ $hash{$sequence} }; 

Вот моя версия вашей программы:

#!/usr/bin/perl 

use strict; 
use warnings; 

use strict; 
use warnings; 

# open my $in, '<', '/path/to/file') or die $!; 
my $in = \*DATA; #use internal data file instead for testing 
my $count = 0; 

my %hash = (
    AAAAA => [ "QWERT", "YUIOP" ], 
    BBBBB => [ "ASDFG", "HJKL", "ZXCVB" ], 
); 

while (<$in>) { 
    chomp; 
    my $hash; 
    my @elements = split "\t"; 
    my $number = grep exists $hash{$_}, @elements; 
    #open my $out, '>', "/path/out/Cluster__Number$._$number.txt" or die $!; 
    my $out = \*STDOUT; # likewise use STDOUT for testing 
    for my $sequence (@elements) { 
     if (exists $hash{$sequence}) { 
      my $out_seq = shift @{ $hash{$sequence} }; 
      # if you want to repeat 
      push @{ $hash{$sequence} }, $out_seq; 
      # if you want to remove $sequence when they run out 
      # delete $hash{$sequence} unless @{ $hash{$sequence} }; 

      print $out ">$sequence\n$out_seq\n"; 
     } else { 
      warn "Key [$sequence] Doesn't Exist ", ++$count, "\n"; 
     } 
    } 
} 

__DATA__ 
AAAAA AAAAA 
CCCCC 
BBBBB BBBBB BBBBB 
+0

Спасибо Chas. Оуэнс. Хороший ответ. – Rob

2

В этой строке:

print $out ">$sequence\n$hash{$sequence}\n"; 

... $hash{$sequence} является ссылкой на массив. Перед печатью вы должны разыменовать указанный массив. Вот пример печати $sequence, затем печатает элементы $hash{$sequence} массива на следующей строке, с элементами, разделенных запятой:

print $out ">$sequence\n"; 
print $out join ', ', @{ $hash{$sequence} };