Bioperl 是否有相当于 Seq 对象数组的 IO::ScalarArray ?

发布于 2024-08-29 20:34:02 字数 1065 浏览 15 评论 0原文

在 Perl 中,我们有 IO:: ScalarArray 用于将数组的元素视为文件的行。在 BioPerl 中,我们有 Bio::SeqIO< /code>,它可以生成一个文件句柄来读取和写入 Bio::Seq 对象,而不是表示文本行的字符串。我想将两者结合起来:我想获得一个句柄,该句柄从此类对象的数组中读取连续的 Bio::Seq 对象。有什么办法可以做到这一点吗?对我来说实现一个执行此操作的模块会很简单吗?

我想要这个的原因是我希望能够编写一个接受 Bio::SeqIO 句柄或 Bio::Seq 对象数组的子例程,我想避免根据我得到的输入类型编写单独的循环。也许下面的内容比编写我自己的 IO 模块更好?

sub process_sequences {
    my $input = $_[0];

    # read either from array of Bio::Seq or from Bio::SeqIO
    my $nextseq;
    if (ref $input eq 'ARRAY') {
        my $pos = 0
        $nextseq = sub { return $input->[$pos++] if $pos < @$input}; }
    }
    else {
        $nextseq = sub { $input->getline(); }
    }

    while (my $seq = $nextseq->()) {
        do_cool_stuff_with($seq)
    }
}

In Perl, we have IO::ScalarArray for treating the elements of an array like the lines of a file. In BioPerl, we have Bio::SeqIO, which can produce a filehandle that reads and writes Bio::Seq objects instead of strings representing lines of text. I would like to do a combination of the two: I would like to obtain a handle that reads successive Bio::Seq objects from an array of such objects. Is there any way to do this? Would it be trivial for me to implement a module that does this?

My reason for wanting this is that I would like to be able to write a subroutine that accepts either a Bio::SeqIO handle or an array of Bio::Seq objects, and I'd like to avoid writing separate loops based on what kind of input I get. Perhaps the following would be better than writing my own IO module?

sub process_sequences {
    my $input = $_[0];

    # read either from array of Bio::Seq or from Bio::SeqIO
    my $nextseq;
    if (ref $input eq 'ARRAY') {
        my $pos = 0
        $nextseq = sub { return $input->[$pos++] if $pos < @$input}; }
    }
    else {
        $nextseq = sub { $input->getline(); }
    }

    while (my $seq = $nextseq->()) {
        do_cool_stuff_with($seq)
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

孤独陪着我 2024-09-05 20:34:02

您的解决方案看起来应该有效。除非你真的想花很多时间来解决这个问题,否则就继续下去,直到你不再喜欢为止。我可能会这样写,以避免多次输入变量名称:

my $nextseq = do {
     if (ref $input eq ref [] ) {
         my $pos = 0;  #maybe a state variable if you have Perl 5.10
         sub { return $input->[$pos++] if $pos < @$input} }
         }
     else {
         sub { $input->getline() }
     }
 }

不过,如果您对迭代器感兴趣,请查看 Mark Jason Dominus 的 Higher Order Perl,他在其中讨论了执行此类操作的各种方法。

Your solution looks like it should work. Unless you really want to spend a lot of time solving this problem, go with it until you don't like it anymore. I might have written that like so to avoid typing the variable name several times:

my $nextseq = do {
     if (ref $input eq ref [] ) {
         my $pos = 0;  #maybe a state variable if you have Perl 5.10
         sub { return $input->[$pos++] if $pos < @$input} }
         }
     else {
         sub { $input->getline() }
     }
 }

If you're interested in iterators, though, check out Mark Jason Dominus's Higher Order Perl, where he talks about all sorts of ways to do these sorts of things.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文