2

配列にアイテムが繰り返されているかどうかを確認したいのですが、16.000を超えているので、自動化します。他の方法もあるかもしれませんが、これから始めました。簡単なコマンドがない限り、これを終了したいと思います。私が行っているのは、ある配列から別の配列にシフトしてプッシュすることです。このようにして、宛先配列が「配列内」にあるかどうかを確認します(PHPにそのようなコマンドがあるように)。

だから、私はこのサブルーチンを手に入れました、そしてそれはリテラルで動作します、しかしそれは変数では動作しません。それは「eq」または私が必要とするもののためです。'sourcefile'には、宛先配列の1つ以上の単語が含まれます。

// Here I just fetch my file


    $listamails = <STDIN>;
    # Remove the newlines filename
    chomp $listamails;
    # open the file, or exit
    unless ( open(MAILS, $listamails) ) {

    print "Cannot open file \"$listamails\"\n\n";
    exit;
    }
    # Read the list of mails from the file, and store it
    # into the array variable @sourcefile
    @sourcefile = <MAILS>;
    # Close the handle - we've read all the data into @sourcefile now.
    close MAILS;


    my @destination = ('hi', 'bye');

    sub in_array
    {
       my ($destination,$search_for) = @_;
       return grep {$search_for eq $_} @$destination;
    }

    for($i = 0; $i <=100; $i ++)

    {
      $elemento = shift @sourcefile;
      if(in_array(\@destination, $elemento))
      {
        print  "it is";
      }
      else
      {
        print "it aint there";
      }
    }

さて、そこに$ elementoを含める代わりに、「hi」を入れると機能し、「hi」でもある$ ​​elementoの値を出力しましたが、変数を入れると機能しません。これは「eq」のせいですが、他に何を入れるべきかわかりません。==とすると、「hi」は数値ではないと文句を言います。

4

4 に答える 4

4

個別の値が必要な場合は、ハッシュを考えてください。

my %seen;
@seen{ @array } = (); 

if (keys %seen == @array) {
    print "\@array has no duplicate values\n";
}
于 2012-06-30T13:39:54.090 に答える
2

何が欲しいのかはっきりしていません。重要なのが最初の文だけである場合(「配列内にアイテムが繰り返されているかどうかを確認したい」)、次を使用できます。

my %seen;
if (grep ++$seen{$_} >= 2, @array) {
   say "Has duplicates";
}

アレイが大きいとおっしゃっていたので、重複を見つけたらすぐに停止する方が速いかもしれません。

my %seen;
for (@array) {
   if (++$seen{$_} == 2) {
      say "Has duplicates";
      last;
   }
}
于 2012-06-30T16:39:11.747 に答える
1

ちなみに、多数のアイテムで重複を探す場合は、並べ替えに基づく戦略を使用する方がはるかに高速です。アイテムを並べ替えると、すべての重複が隣り合って表示されるため、重複があるかどうかを判断するには、前の重複と比較するだけです。

@sorted = sort @sourcefile;
for (my $i = 1; $i < @sorted; ++$i) {   # Start at 1 because we'll check the previous one
    print "$sorted[$i] is a duplicate!\n" if $sorted[$i] eq $sorted[$i - 1];
}

これにより、複数の重複がある場合に複数の重複メッセージが出力されますが、クリーンアップすることができます。

于 2012-06-30T13:41:39.127 に答える
1

eugene yが言ったように、ハッシュは間違いなくここに行く方法です。投稿したコードをハッシュベースのメソッドに直接翻訳すると、次のようになります(途中でもう少しPerlishnessが追加されます)。

my @destination = ('hi', 'bye');
my %in_array = map { $_ => 1 } @destination;

for my $i (0 .. 100) {
  $elemento = shift @sourcefile;
  if(exists $in_array{$elemento})
  {
    print  "it is";
  }
  else
  {
    print "it aint there";
  }
}

@sourcefileまた、 (最初の101個の要素をテストするのではなく)のすべての要素をに対してチェックする場合は、行を@destination次のように置き換える必要があります。for

while (@sourcefile) {

chompまた、ファイルから読み取った値も忘れないでください。ファイルから読み取られた行の末尾には改行があり(\r\nまたは\n最初の質問のコメントで言及されています)、これによりeq、ハッシュルックアップとハッシュルックアップの両方で、一致する値が異なることが報告されます。sortこれが、コードが最初から正しく機能せず、使用またはハッシュに変更しても修正されない理由である可能性があります。最初chompに入力して機能させ、次に使用sortまたはハッシュして効率的にします。

于 2012-06-30T15:11:32.233 に答える