配列の重複要素を削除する
Perl/CGIプログラム の 配列 を構成している各要素の中で、その内容が重複しているものを削除しそれらをひとつにまとめてみましょう。
Perl/CGIプログラミング をしていると、配列のようなリスト形式になっているデータを扱う場面というのは多々あります。
「 Perl/CGIプログラムの配列変数を指定条件で並び替える 」といったことをやりました。
ということで今回は、リスト形式になっているデータの中から同じ内容のものを検索し、もし重複しているものがあれば2つ目以降を削除する(取り除いてひとつにまとめる)ということをやってみましょう。
配列の重複要素をまとめる
Perl/CGIプログラムの配列変数を構成している各要素をチェックし、もし同じものがあれば2つ目以降を削除して、要素の重複しない配列を作成します。
#!/usr/bin/perl
use strict;
my @array = (1, 3, 3, 5, 7);
my $resultarrayreference = &UniqueArray(\@array);
print "Content-type: text/html\n\n";
print "@{$resultarrayreference}";
exit;
sub UniqueArray {
my @arrayreference = @_;
my @unique = ();
my %hash = ();
foreach my $arraynumber (@arrayreference) {
foreach my $key (@{$arraynumber}) {
next if ($key eq '');
next if ($hash{$key});
$hash{$key} = 1;
push @unique, $key;
}
}
return \@unique;
}
__END__
このPerl/CGIプログラムを実行すると、「1 3 5 7」と表示されます。
サブルーチン UniqueArrayに、重複要素をひとつにまとめたい 配列 を リファレンス 形式で渡すと、その結果をリファレンス形式の配列として返してくれます。
Perl/CGIプログラムを見ていただければわかるように、難しいことは何もしていません。
配列の重複要素のチェックには、 連想配列 を使っています。
連想配列のキーは、その構造上同名のものは存在できません。
なので foreachループ で、渡された配列の各要素をキーとして連想配列を作成しています。
もし重複している要素があった場合、すでに連想配列のキーとして作成済みなので、 if文 が成立し次に飛ばされます。
このようにして重複している2つ目以降の要素が取り除かれた連想配列のキーのリストが作成されます。
もしデータの順番を気にしないのであれば、「return (keys %hash);」とすれば、重複要素のない配列(リスト形式のデータ)を返すことができます。
しかし、今回はデータの並び順も保ちたいので、順次 push関数 を使って「@unique」に作成した連想配列のキーを代入させています。
2つ以上の配列で重複要素をまとめる
今度は2種類の配列でやってみましょう。
前述と同じように、構成している各要素をチェックし、もし同じものがあれば2つ目以降を削除して、要素の重複しない1つの配列を作り上げます。
#!/usr/bin/perl
use strict;
my @array1 = ('P', 'e', 'e', 'r', 'l', '/');
my @array2 = ('P', 'C', 'G', 'I', 'C');
my $resultarrayreference = &UniqueArray(\@array1, \@array2);
print "Content-type: text/html\n\n";
print @{$resultarrayreference};
exit;
sub UniqueArray {
my @arrayreference = @_;
my @unique = ();
my %hash = ();
foreach my $arraynumber (@arrayreference) {
foreach my $key (@{$arraynumber}) {
next if ($key eq '');
next if ($hash{$key});
$hash{$key} = 1;
push @unique, $key;
}
}
return \@unique;
}
__END__
このPerl/CGIプログラムを実行すると「Perl/CGI」と表示されます。
改造したのはメイン処理部分のみで、UniqueArray関数の内容は変わっていません。