3

基本的に私がやろうとしているのは、大きなテキスト ファイルを検索して、"ヒットが見つかりませんでした"、および識別子に一致するコピーを新しいリストにコピーします。この最初の部分は問題ありませんが、理解できないように見えるのは、配列の要素を正確に 5 つのインデックスをコピーする方法です (これはidentifier) を別の配列にコピーします。

私はこのようなものを試しました、

$fastafile = 'HpHcTEST.txt';
open(FASTAFILE, $fastafile);
@seq = <FASTAFILE>;
my $fastaid;
foreach (@seq) {
    if ($_ =~ /\*\*\*\*\* No hits found \*\*\*\*\*/){
        $fastaid .= $_[-5];
    }
}

print "here are the IDs\n";
print $fastaid;

[-5] の大量のバリアントを使用しましたが、どれも機能しませんでした..一致が見つかった場合に、前の要素を逆参照して取得する方法に関するドキュメントが見つからないようです。これをコーディングする方法を知っている人はいますか?

どうぞよろしくお願いいたします。

アンドリュー

4

4 に答える 4

3

簡単な修正

@seqそれを行う1つの方法は、インデックスを持って歩くことです。

my @fastaid;

for (my $i = 0; $i < @seq; ++$i) {
    if ($seq[$i] =~ /\*\*\*\*\* No hits found \*\*\*\*\*/){
        push @fastaid, $seq[$i - 5] if $i >= 5;
    }
}

スカラーから という名前の配列への変更に注意してください@fastaid

print "Here are the IDs:\n";
print "  - $_\n" for @fastaid;

あるいは

print "Here are the IDs:\n",
      map "  - $_\n", @fastaid;

磨きを加える

以下のコメントにあるようbrian d foyに、コードはよりエレガントで、意図をより直接的に表現できます。

my $id_offset = 5;
my @fastaid;

for ($id_offset .. $#seq) {
    if ($seq[$_] =~ /\*\*\*\*\* No hits found \*\*\*\*\*/){
        push @fastaid, $seq[$_ - $id_offset];
    }
}

perldata の「スカラー値」セクションに記載されているように、$#seqは の最後の要素のインデックス または です@seq..範囲演算子は、長さが要素@seqより少ない場合を正しく処理します。$id_offset

明示的な regex-bind 演算子は、まだ少し不完全です。あなたは一緒に行くことができます

my $id_offset = 5;
my @fastaid;

for my $i ($id_offset .. $#seq) {
  for ($seq[$i]) {
    push @fastaid, $seq[$i - $id_offset]
      if /\*\*\*\*\* No hits found \*\*\*\*\*/;
  }
}

または、少なくともバージョン 5.10 を使用している場合

use feature 'switch';

# ...

my $id_offset = 5;
my @fastaid;

for my $i ($id_offset .. $#seq) {
  given ($seq[$i]) {
    when (/\*\*\*\*\* No hits found \*\*\*\*\*/) {
      push @fastaid, $seq[$i - $id_offset];
    }
  }
}

歴史的メモ

昔、配列トラバーサルのインデックスを追跡するために転用するという話があった$#ので、次のように書くことができました

for (@fastaid) {
    if (/\*\*\*\*\* No hits found \*\*\*\*\*/) {
        push @fastaid, $seq[$# - 5] if $# >= 5;
    }
}

しかし、それは決して実現しませんでした。

于 2012-04-24T21:12:24.967 に答える
3

インデックスと添字を繰り返し処理して、配列要素を取得できます。

for (5..$#seq) {
    $fastaid .= $seq[$_-5] if $seq[$_] =~ /your_regex/;
}

Perl 5.12 以降では、以下も使用できますeach

while (my ($index, $value) = each @seq) {
    next if $index < 5;
    $fastaid .= $seq[$index-5] if $value =~ /your_regex/;
}
于 2012-04-24T21:15:52.500 に答える
2
my @fasta_id = map { $seq[$_] =~ /your_regex/ ? $seq[$_-5] : () } 5 .. $#seq;
于 2012-04-25T06:59:56.520 に答える
-2

「foreach」の代わりに「for」ループを使用し、

for ($index=0; $index < $#seq + 1; $index++) {
    if ($seq[$index] =~ /\*\*\*\*\* No hits found \*\*\*\*\*/){
        $fastaid .= $seq[$index-5];
    }
}
于 2012-04-24T21:19:01.737 に答える