2

私は1つのシナリオでいくつかの助けを探しています。

要件:

いくつかの検証を通じて、1つの配列で次の種類の値を追跡しました。

@array_name = ("Rajesh","Raju","Ram","John","peter");

これで、いくつかの背景から、「Rajesh」、「Ram」、「peter」が重複したエントリであることがわかったので、出力は次のようになります。

@array_name = ("Rajesh","Raju","John");
# or 
@array_name = ("Ram","Raju","John");
# or 
@array_name = ("peter","Raju","John");

以下のようなサンプルプログラムを実行しましたが、満足できません...

    my $spcific_output ="";
    my $output ="";

    foreach my $name (@array_name) 
    {
        if($name eq "Rajesh" || $name eq "Ram" || $name eq "peter")
        {
            $spcific_output = "Rajesh and Ram and peter");
        }
        else
        {
            $output .= "My Name is $name";
        }
    } 
    $output .= $spcific_output;

これを達成するための最良の方法はありますか?

4

2 に答える 2

2

v5.10以降を使用している場合は、重複する名前のアレイでスマートマッチングを使用できます。

#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;

my @names = qw(Rajesh Raju Ram John Peter);
my @dupl = qw(Rajesh Ram Peter);
my $seen;

my @names = grep {$_ ~~ @dupl ? !$seen++ : 1} @names;

print Dumper \@names;

出力:

$VAR1 = [
          'Rajesh',
          'Raju',
          'John'
        ];

の条件は、からの名前がにあるかどうかを評価し、grepが0の場合にのみ保持されます。それ以外の場合は()が評価されて保持されます。!$seen++@names@dupl$_$seen1true$_

于 2012-06-01T07:42:15.923 に答える
2

Perlでは、コレクションから一意の値が必要な場合はいつでも、ハッシュを使用して重複を自動的に折りたたむのに役立つ方法、または少なくともすでに見た値を思い出すのに役立つ方法を考えてください。たとえば、2つのハッシュから一意のキーを取得するにはどうすればよいですか?を参照してください。PerlFAQのセクション4にあります。

交換可能な名前のセットがあるため、ケースは少し注意が必要です。そのため、この情報を記録する必要があります。

sub add_names {
  my $equivalent = shift;

  for (@_) {
    my @names = map lc, @$_;
    for (@names) {
      die "$0: overlap on name '$_'" if exists $equivalent->{$_};
      $equivalent->{$_} = \@names;
    }
  }

  $equivalent;
}

ここに$equivalent、ハッシュへの参照があります。電話した後

add_names $equivalent, [ qw/ Rajesh Ram peter / ];

ハッシュにはキー、、があり'rajesh''ram'その'peter'値はすべて[ 'rajesh', 'ram', 'peter' ]。です。このように構成することは、最初に出会った名前に関係なく、名前の完全なセットに到達できることを意味します。

また、次のように、1回の呼び出しで複数の名前のセットをスタックできることにも注意してください。

add_names $equivalent, [ qw/ Rajesh Ram peter / ],
                       [ qw/ Jim Bob Bubba / ];

名前がマッピングされたら、リストを処理して、見つかった各セットの名を保持できます。与えられた名前について、私たちが以前にそれまたはそれに相当するものを見たことがあるかどうかを確認してください。まだ見たことがない場合は、名前を保存し、すべての同等のものに見られるようにマークを付けます。

sub remove_duplicates {
  my $equivalent = shift;

  my %seen;
  my @uniques;
  foreach my $name (@_) {
    my $normal = lc $name;
    unless ($seen{$normal}) {
      push @uniques, $name;
      ++$seen{$_} for @{ $equivalent->{$normal} };
    }
  }

  wantarray ? @uniques : \@uniques;
}

下部のwantarrayビットは、戻り値を呼び出し元のコンテキストに適合させるための一般的なPerlイディオムです。呼び出し元が配列を必要とする場合は、配列を返します。そうでない場合は、スカラー、つまり一意の名前の配列への参照を返します。

すべてをまとめると

my $equivalent = {};
add_names $equivalent, [qw/ Rajesh Ram peter /];

my @array_name = ("Rajesh","Raju","Ram","John","peter");
print $_, "\n" for remove_duplicates $equivalent, @array_name;

出力:

ラジェッシュ
ラジュ
ジョン
于 2012-06-01T12:32:42.457 に答える