2017-05-16 8 views
-1

次は、正規表現を使用してカンマ区切りファイルを検索する例です。誰もが以下のコードをハッシュマップ検索に変換する方法を知っていますか?一致した場合、コードは両方のファイルから元の行を返す必要があります。ハッシュマップの使用とコンマ区切りファイルの検索

必ずしもハッシュマップを使用する必要はありません。あなたの解決策には、grep、ハッシュ、スマート検索、最初のものなど、配列を検索するための他の高速な方法も含めることができます。

これらの文書には何千ものレコードがあります。目的は、file1.csvの3列目とfile2.csvの4列目の類似項目を見つけることです。一致するものがあれば、両方の文書の行を結合します。

更新は:それは@データ2列

my $data_file1 = "file1.csv"; #contains in this file "james,smith,3 kids" 
my $data_file2 = "file2.csv"; #contains in this file "jim,jones,tall,3 kids" 

my $handle1; 
my @temp_data1, @temp_data2; 

open $handle1, '<', $data_file1; 
chomp(@data1 = <$handle1>); 
close $handle1;  

open $handle1, '<', $data_file2; 
chomp(@data2 = <$handle1>); 
close $handle1; 

foreach my $line1 (@data1) 
{ 
    @temp_data1 = split /,/ , $line1; 
    $not_found =1; 
    foreach my $line2 (@data2) 
    {   
     @temp_data2 = split /,/ , $line2; 

     if($temp_data2[3] =~ /$temp_data1[2]$/) 
     { 
      $not_found =0; 
      say $line1 .",". $line2; 
     } 
    } 
    if($not_found) 
    { 
     say "$line1 was not found"; 
    } 
} 
+0

*「ハッシュマップは必ずしも使用する必要はありません」*これは学校の割り当てですか? – Borodin

+0

'my @ temp_data1、@ temp_data2'行は' @ temp_data1'を字句配列変数として宣言しますが、 'my_'は' @ temp_data2'には適用されません。これはカンマ演算子よりも厳密に束縛されるからです。あなたは 'my @ temp_data1;' @ temp_data2;と同等のものを書いていますが、それだけでステートメント内の配列を最適化することは最適化されます。 'my'は' use strict'がなければほとんど役に立たないし、あなたが書いた* Perlプログラムのすべての上に 'use warnings 'all''と一緒に使う必要があります。その単純な尺度はあなたにあなたのエラーを警告していました。 – Borodin

+0

'$ not_found = 1'を初期化するのは混乱します。 '$ found'を使って論理を逆転させ、' $ 'が見つからなければ$ line1が "見つからない"と言うのが良いでしょう。 – Borodin

答えて

2

には何も一致しない場合、$ LINE1を印刷するハッシュキーと行としてキーフィールドを使用してハッシュを読み込む必要があることを言及するのを忘れました値として。次に、他のファイルを調べて、ハッシュで一致するものを探します。

use Text::CSV_XS qw(); 

@ARGV == 2 
    or die("usage\n"); 

my ($data_file1, $data_file2) = @ARGV; 

open(my $fh1, '<', $data_file1); 
    or die("Can't open \"$data_file1\": $!\n"); 
open(my $fh2, '<', $data_file2); 
    or die("Can't open \"$data_file2\": $!\n"); 

my $csv = Text::CSV_XS->new({ auto_diag => 2, binary => 1 }); 

my %data; 
while (my $row = $csv->getline($fh2)) { 
    $data{ $row->[3] } = $row; 
} 

while (my $row = $csv->getline($fh1)) { 
    if (my $linked_row = $data{ $row->[2] }) { 
     $csv->say(\*STDOUT, [ @$row, @$linked_row ]); 
    } else { 
     $csv->say(\*STDERR, $row); 
    } 
} 

使用法:

script file1.csv file2.csv >merged.csv 2>unpaired.csv 
  • 最初のファイルの3列のみ一意の値が含まれて想定しています。
  • 2番目のファイルの4番目の列に一意の値のみが含まれていると仮定します。

CPU:O(N * M)ではなくO(N + M)です。
Mem:O(N + M)の代わりにO(M)。
ここで、Nは最初のファイルの要素の数であり、
であり、Mは2番目のファイルの要素の数です。

+0

@ data2の配列に一致しない場合は、$ line1を出力しなければならないことを忘れた – Jelani

+0

ハッシュにファイル2をロードする必要があります。一定。 – ikegami

+0

うん...これは完璧に動作します...ありがとう! – Jelani

0
my $data_file1 = "file1.csv"; #contains in this file "james,smith,3 kids" 
my $data_file2 = "file2.csv"; #contains in this file "jim,jones,tall,3 kids" 

my $handle1; 

my %searchHash; 

open $handle1, '<', $data_file1; 
while (my $line = <$handle1>) { 
    chomp($line); 
    $searchHash{(split /,/,$line)[2]} = 0; 
} 
close $handle1;  

open $handle1, '<', $data_file2; 
while (my $line = <$handle1>) { 
    chomp($line); 
    my $key = (split /,/,$line)[3]; 
    $searchHash{$key}++ if(defined $searchHash{$key}); 
} 
close $handle1; 

foreach my $key (keys %searchHash) { 
    print "$key ($searchHash{$key})\n"; 
} 
+0

リクエスト結果( 'james、smith、3 kids、jim、jones、tall、3 kids')は生成されません。 – ikegami

+0

どういう意味ですか?一致するものが1つ見つかります。 – Andrey

+0

「ジェイムス、スミス、3人の子供、ジム、ジョーンズ、背の高い、3人の子供」、「3人の子供」は印刷しないでください – ikegami

関連する問題