2017-03-31 11 views
0

私はちょっとジャムになり、誰かがそれをクリアできるかどうか疑問に思っていました。 [データ@]配列内の配列に重複があるかどうかを調べる(多次元配列)

  1. @array [@filenames]を保持して多次元配列を作成する.txtファイル
  2. を含むデータの束を開く
  3. ファイルが重複している検索:私は何をしたいことはあり お互いのデータ

の観点からここで私は自分のデータを取得し、配列にそれを置くために正規表現を使用して、変数にファイルを読ま:

while (my $row = <$fh>) { 
     unless ($. == 0) { 
      { 
      local $/; # enable slurp 
      @datalist = <$fh> =~ /\s*\d*\/\s*\d*\|\s*(.*?)\|.*?(?:.*?\|){4}\s*(\S*)\|(\S*).*\|/g; #extract article numbers # $1 = article number, $2 = quantity, $3 = unit 
      } 
      push(@arrayofarrays,[@datalist]); 
      push(@filenames,$file); 
      last; 
      } 
     } 
     $numr++; 
} 
open(my $feh,">","test.txt"); 
print {$feh} Dumper \@arrayofarrays; 

Aダンパ(pseudoresultsはそれが読みやすいと短くする)私のデータが正常に見えることを示しています

$VAR1 = [ 
      [ 
      'data type1', 
      'data type2', 
      'data type3', 
      'data type1', 
      'data type2', 
      'data type3', 
      ... 
      ], 
      [ 
      'data type1', 
      'data type2', 
      'data type3', 
      ... 
      ], 
     ... 
    ]; 

誰でもデータのセット間の重複をチェックする簡単な方法を知っているのであれば、私は思ったんだけど?あなたが@dataListを作成すると、そのチェックのためのキーを作成

my $i = 0; 
my $j = 0; 
while ($i <= scalar @arrayofarrays) { 
    $j = 0; 
    while ($j <= scalar @arrayofarrays) { 
     if (@{$arrayofarrays[$i]} eq @{$arrayofarrays[$j]}) { 
      print "\n'$filenames[$i]' is duplicate to '$filenames[$j]'."; 
      } $j++; 
     } $i++; 
    } 
+0

おそらくあなたはあなたの質問を編集することができます(http://stackoverflow.com/posts/43140260/edit)私たちを表示するあなたが期待している出力。あなたのサンプルコードはむしろ混乱しています。 2番目のレベル配列の各要素の数を比較しています。要素の数ではありません。そして、数値比較( '==')ではなく文字列比較( 'eq')を使ってそれらの数値を比較しています。 –

+2

どのファイルが同一であるかを確認したい場合は、すべてをメモリに読み込まないようにしてください。 ['Digest :: MD5'](https://metacpan.org/pod/Digest::MD5)を使ってそれぞれのチェックサムを作成し、結果を比較するだけです。 – Borodin

答えて

0

を:私は私は私が何をする必要があるかのように、より良いアイデアを与えるかもしれない試してみました何

使用して、個々のデータ・セットを印刷することができます知っていますそのキーのあなたはプッシュを行う前に、のようなもの:

my %checkHash=undef; 
my $key=arrayKey(\@datalist); 
if (!$checkHash{$key}) { 
    push(@arrayofarrays,[@datalist]); 
    push(@filenames,$file); 
    $checkHash{$key}=1; 
    last; 
} 

sub arrayKey($) { 
    my $arrayRef = shift; 
    my $output=undef; 
    for (@$arrayRef) { 
     if (ref($_) eq 'ARRAY') { 
      $output.="["; 
      $output.=arrayKey($_); 
      $output.="]"; 
     } 
     else { 
      $output.="$_,"; 
     } 
    } 
    return $output; 
} 
+3

'arrayKey'の唯一のパラメータが配列参照でなければならない場合、確実に' \ @ 'は' $ 'よりも優れたプロトタイプになります。サブルーチンを 'arrayKey(@datalist)'として呼び出すことができ、それでもすべてが機能します。多くの人のように、プロトタイプは価値があるよりもはるかにトラブルであり、初心者向けのサンプルでは使用しないと思います。 –

+1

@DaveCross優れた点、ありがとう。 –

1

代わりの配列の配列私は(必要に応じてチェックサムにそれらを回して文字列にサブアレイを平坦化することによりサブアレイのデータから鍵を生成する、配列のハッシュを作成したいですこれは多次元サブアレイに適している)。あなたはPerlMonksにこの議論を読むことをお勧めします:サブアレイ内の重複データと、既に既存のアレイ(あなたがhere on ideone.comそれをテストすること)与えられた

http://www.perlmonks.org/?node_id=1121378

抽象例:

#!/usr/bin/perl 
use strict; 
use warnings; 
use Data::Dumper; 
my @array = (
    [1,'John','ABXC12132328'], 
    [0,'John','ABXC12132322'], 
    [0,'John','ABXC12132322'], 
    [0,'John','ABXC12132322'], 
    [0,'John','ABXC12132322'], 
    [0,'John','ABXC12132322'], 
    [0,'John','ABXC12132322'], 
    [0,'John','ABXC12132322'], 
    [0,'John','ABXC12132322'], 
    [0,'John','ABXC12132322'], 
    [0,'John','ABXC12132322'], 
    [0,'John','ABXC12132322'], 
    [0,'John','ABXC12132322'], 
    [0,'John','ABXC12132322'], 
    [0,'John','ABXC12132322'] 
); 
my %uniq_helper =(); 
my @uniq_data = grep { !$uniq_helper{"@$_"}++ } @array; 
print Dumper(\%uniq_helper) . "\n"; 
print Dumper(\@uniq_data) . "\n"; 

あなたのケースのためにこれはおそらく次のようになります:

my %datalist; 
while (my $row = <$fh>) { 
    unless ($. == 0) { 
     { 
      local $/; # enable slurp 
      @data = <$fh> =~ /\s*\d*\/\s*\d*\|\s*(.*?)\|.*?(?:.*?\|){4}\s*(\S*)\|(\S*).*\|/g; #extract article numbers # $1 = article number, $2 = quantity, $3 = unit 
     } 
     $datalist{"@data"} = \@data; 
     push(@filenames,$file); 
     last; 
    } 
} 
$numr++;