2017-05-16 75 views
-1

下面是使用正則表達式搜索逗號分隔文件的示例。有誰知道如何將下面的代碼轉換爲哈希映射搜索。如果匹配,代碼應該從兩個文件中返回原始行。使用哈希映射並搜索逗號分隔文件

您不必使用散列映射。您的解決方案可以包含任何其他更快的搜索數組的方法,例如grep,hash,智能搜索,第一等。

這些文檔中有成千上萬條記錄。目標是在file1.csv的第3列和file2.csv的第4列中找到類似的項目。如果有匹配,則從兩個文檔中加入這些行。

更新:忘了提,它應打印$一號線,如果它不@ DATA2陣列

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;'並且只是在一個聲明中提到一個數組將被優化。如果沒有'use strict','my'的用處很少,而且你*必須總是和*'*'每個你編寫的Perl程序的頂部一起使用'use warnings'all''。這個簡單的措施會提醒你你的錯誤。 – Borodin

+0

初始化'$ not_found = 1'會令人困惑。使用'$ found'並反轉邏輯會更好,用'say'結束$ line1找不到「除非$ found」。 – Borodin

回答

2

在匹配任何使用鍵字段作爲哈希鍵和行填充的哈希作爲價值。然後瀏覽其他文件,在哈希中查找匹配項。

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 
  • 假設第一個文件的第三列只包含唯一值。
  • 假設第二個文件的第四列僅包含唯一值。

CPU:O(N + M)而不是O(N * M)。
Mem:O(M)代替O(N + M)。
其中N是第一個文件中元素的數量,
而M是第二個文件中元素的數量。

+0

忘了提及它應該打印$ line1,如果它不匹配@ data2數組中的任何內容 – 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

不產生請求結果('詹姆斯,史密斯,3個孩子,吉姆,瓊斯,高個子,3個孩子')。 – ikegami

+0

你是什麼意思?它找到一個匹配。 – Andrey

+0

它需要打印'詹姆斯,史密斯,3個孩子,吉姆,瓊斯,高個子,3個孩子',而不是'3個孩子' – ikegami