2017-04-13 16 views
1

私はこのようになりますテキストファイルを解析しています:テキストファイルを2つの配列に分割する方法は?

ABCD 
EFGH 
IJKL 

MNOP 
QRST 
UVWX 

それは2つの4x3のアレイにつながるように、Perlでこれを解析することは可能ですか?たとえば、array1[2][2] = Kand array2[0][1] = Nです。 コード:手順コメントで説明

#!/usr/bin/perl 
use strict; 
use warnings; 
use diagnostics; 

open(FH, '<', 'gwas.txt') or die "Couldn't open file $!"; 

while(<FH>) { 

    #parse file into 2 arrays 
} 
close(FH); 
+1

これはパズルですか?どのような計数システムが指標「(2,4)」と「N」と「(1,0)」を持つ「K」を持っていますか?説明できますか?しかし、まず、あなたがしたこと、そしてあなたがその問題を持っていることを私たちに示すことができますか?ここの質問は、あなたのコードについてのものであると予想されます。 – zdim

+0

@zdim私の間違い!ちょうどそれらを修正し、コードを追加しました。 –

+0

これは良いことですが、ありがとうございます(まだ、私はあなたが 'a [2] [2] == K' ...を意味すると思います)。コードについては、データ構造にそれぞれの_references_を持たせて多次元構造を作成します。スロット。参考文献:チュートリアル[perlreftut](http://perldoc.perl.org/perlreftut.html)、料理レッスン[perldsc](http://perldoc.perl.org/perldsc.html)。あなたは 'pelrdsc'の配列の配列を必要とします – zdim

答えて

1

、凝縮

my @matrix = map { [ split '', $_ ] } <$fh>; 

ダイヤモンドオペレータlist context戻り値<>すべての行(I/O operatorsを参照)、それぞれがブロックによって処理されますmap、返されるリストは@matrixに割り当てられます。文字('')に各行($_)を破壊し、そしてanonymous arrayは、そのリスト([...])で作られているsplitブロック内

splitのデフォルトを指定すると、これはmap { [ split '' ] }と書くことができます。

常に字句ファイルハンドルを使用し、それは良いでしょうそのよう

my $file = 'gwas.txt'; 
open my $fh, '<', $file or die "Couldn't open $file: $!"; 

としては、これは1つの配列にファイル全体を処理し、コメントで指摘しました。 2つのテキストブロックをそれぞれ独自の配列に処理するために、ループとして記述できます(ブロックを区別するために空行を使用します)。

my @matrix; 
my $index = 0;  
while (<$fh>) { 
    $matrix[$index++] = [ split '', $_ ]; 
} 

これは、線要素と無名配列[ ... ]を行い、アレイ@matrix(インクリメント指数)で$indexスポットに割り当てます。これを行うもう1つの方法は、すべての反復で新しい配列が作成され、その配列への参照が割り当てられます。

次に、ブロックを区別するために空行を使用する必要があります。また、2つの配列を管理する必要があります。他のデータ構造(配列など)の配列(行列)への参照を持つことでうまくいきます。

これは、データについての仮定を一般的に保持しています。

参照番号perlreftutのチュートリアルとデータ構造のチュートリアルperldscを参照してください。

answer by xxfelixxxも参照してください。これはすべて非常にわずかに異なります。

これを行うには他にもいくつかの方法があります。

+0

大丈夫です、それは意味があります。しかし、私の意図は2つの別々の配列を持つことでしたが、現在は1つしかありません。 –

+0

よろしくお願いします。大いに感謝します –

+0

@KyleWeiseああ、私は今あなたが2つの配列を意味するものを見る。あなたは正しいです - これは、空の行に混乱を招いて、両方のテキストブロックを1つに保存します。それは基本的なデモンストレーションのためのものでした。あなたの全体の問題については、そのコメントに概説されているように、ループとして書き出してください。空行をヒットしたら、2番目の配列から始めます。 – zdim

0
#!/usr/bin/env perl 
use strict; 
use warnings; 

my $arrays = []; 
my $count = 0; 
my $row = 0; 

# Read data and store in $arrays 
while(<DATA>) { 
    if (my ($letters) = m/^(\w+)\s*$/) { 
     # Store letters 
     $arrays->[$count]->[$row] = [ split //, $letters ]; 
     $row++; 
    } else { 
     # Next batch 
     $count++; 
     $row = 0; 
    } 
} 

# Print it out with indices 
for my $iarray (0 .. $count) { 
    print "------ Matrix $iarray ------\n"; 
    my @rows = @{ $arrays->[$iarray] }; 
    for my $irow (0 .. $#rows) { 
     my @cols = @{ $rows[$irow] }; 
     for my $icol (0 .. $#cols) { 
      print "($irow,$icol) -> " . $cols[$icol] . "\n"; 
     } 
    } 
} 

__DATA__ 
ABCD 
EFGH 
IJKL 

MNOP 
QRST 
UVWX 

出力

------ Matrix 0 ------ 
(0,0) -> A 
(0,1) -> B 
(0,2) -> C 
(0,3) -> D 
(1,0) -> E 
(1,1) -> F 
(1,2) -> G 
(1,3) -> H 
(2,0) -> I 
(2,1) -> J 
(2,2) -> K 
(2,3) -> L 
------ Matrix 1 ------ 
(0,0) -> M 
(0,1) -> N 
(0,2) -> O 
(0,3) -> P 
(1,0) -> Q 
(1,1) -> R 
(1,2) -> S 
(1,3) -> T 
(2,0) -> U 
(2,1) -> V 
(2,2) -> W 
(2,3) -> X 
1
  1. スプリット段落のアレイにデータ。
  2. すべての段落を行の配列に分割します。
  3. すべての行を文字の配列に分割します。

    my @arrays; 
    { 
        local $/ = ""; # Paragraph mode 
        @arrays = map { [ map { [ split // ] } split /\n/ ] } <>; 
    } 
    

    または

    my @arrays; 
    { 
        local $/ = ""; # Paragraph mode 
        push @arrays, [ map { [ split // ] } split /\n/ ] while <>; 
    } 
    

    彼らが作り出す:

  4. これは、以下のいずれかを用いて達成することができ

$VAR1 = [ 
      [ 
      [ 'A', 'B', 'C', 'D' ], 
      [ 'E', 'F', 'G', 'H' ], 
      [ 'I', 'J', 'K', 'L' ] 
      ], 
      [ 
      [ 'M', 'N', 'O', 'P' ], 
      [ 'Q', 'R', 'S', 'T' ], 
      [ 'U', 'V', 'W', 'X' ] 
      ] 
     ]; 

そうに、

say $arrays[0][2][2]; # K 
say $arrays[1][0][1]; # N 
+0

ありがとう!これはとても簡単です。あなたはオープン/クローズの中括弧で理由を説明できますか?それらは '@配列'の宣言に関連しているのでしょうか、それとも別の意味ですか? –

+0

これらは['map'](http://perldoc.perl.org/functions/map.html)の' map BLOCK LIST'構文の一部です。 – ikegami

+0

出力の印刷方法をほとんど含めることができますか?フォーマットのために 'Data :: Dumper'と仮定します。 –

関連する問題