1

I'm trying to write a perl program that will split up a fasta header:

gi|4140243|dbj|AB022087.1|_Xenopus_laevis_mRNA_for_cytochrome_P450,_complete_cds,_clone_MC1

Into it's | seperated parts:

gi
4140243
dbj
AB022087.1
_Xenopus_laevis_mRNA_for_cytochrome_P450,_complete_cds,_clone_MC1

I can do this using split:

my @hits = split(/\|/, $hits);

my ($gi, $number, $gb, $id, $name);
foreach (@hits) {
  $gi.= "$hits[0]\n";
  $number .= "$hits[1]\n";
  $gb .= "$hits[2]\n";
  $id .= "$hits[3]\n";
  $name .= "$hits[4]\n";
}

my @gi = split('\n', $gi);
my @number = split('\n', $number);
my @gb = split('\n', $gb);
my @id = split('\n', $id);
my @name = split('\n', $name);

Now each part of each header (contained in $hits) is an element in an individual array. What I want to do next is print back each element of each array so that I can produce a list of element[0] for each array, element[1] for each array...

I'm unsure as to whether this will require a hash of hashes or array of arrays.

I'm fairly new to perl so any suggestions would be greatly helpful.

I'm also aware that the above might not be the slickest way of achieving what I want - again any comments would be great!

4

2 回答 2

2

$hits 包含一个还是多个标题?如果它只有一个,那么要将其拆分为变量,您可以执行以下操作:

my ($gi, $number, $gb, $id, $name) = split(/\|/, $hits);

每个变量都将包含相应的值。

如果 $hits 包含多个标题,那么首先只拆分行,然后在循环中拆分每个标题。这是一个示例,结果将是哈希数组:

my @hits = split(/\n/, $hits);
my @result;
for my hit ( @hits ) {
    my ($gi, $number, $gb, $id, $name) = split(/\|/, $hits);
    push(@result, {
        gi => $gi,
        number => $number,
        gb => $gb,
        id => $id,
        name => $name,
    });
}

当然,该示例不包括任何错误检查(例如 - 标头字符串是否真的与格式匹配?),但如果需要,您应该将它们包含在实际应用程序中。

PS:我认为你真的必须从那个开始

于 2013-04-24T11:08:32.183 回答
1

一般来说,数组用于同质数据(“一堆东西”),而哈希用于异构数据(“姓名、数字和生日”)。如果你的数据自然分裂成一堆内部异构的东西(“一堆个人信息记录,每条都有名字、数字和生日”),那么自然的数据结构就是一个 hashref 数组(见注#1)。

在您的情况下,$hits是标题列表。因此,我们将创建一个数组,称为它@headers,其中的每个元素都是一个单独的标头,表示为 hashref。我们可以用 将分隔字符串转换为列表split,也可以用 将一种列表转换为另一种列表map

my @headers = map {
    make_header_hashref($_)
} split(/\n/, $hits);

sub make_header_hashref {
    my ($header_string) = @_;
    my ($gi, $number, $gb, $id, $name) = split(/\|/, $header_string);

    return {
        gi      => $gi,
        number  => $number,
        gb      => $gb,
        id      => $id,
        name    => $name,
    };
}

(我将标头字符串到标头 hashref 的转换拆分为一个子项,因为(a)这就是您在实际代码中所做的,并且(b)它阐明了 .)的结构map。)

您现在有一个 hashrefs 数组,因此您可以遍历它们,否则将标头作为单元而不是属性集合来处理。

note#1:嗯,我们真的想要一个描述关联的对象,实现为表示记录的对象数组。

于 2013-04-24T17:05:18.310 回答