6

モジュール List::MoreUtils によってエクスポートされた uniq 関数を使用して、配列内の uniq 要素を検索しています。ただし、大文字と小文字を区別しない方法で一意の要素を見つけてほしい。どうやってやるの?

Data::Dumper を使用して配列の出力をダンプしました。

#! /usr/bin/perl

use strict;
use warnings;
use Data::Dumper qw(Dumper);
use List::MoreUtils qw(uniq);
use feature "say";

my @elements=<array is formed here>;

my @words=uniq @elements;

say Dumper \@words;

出力:

$VAR1 = [
          'John',
          'john',
          'JohN',
          'JOHN',
          'JoHn',
          'john john'
        ];

予想される出力は次のようになります: john, john john

2 つの要素のみ。残りはすべて同じ単語であるため、フィルタリングする必要があります。大文字と小文字の違いのみです。

大文字と小文字を区別せずに重複した要素を削除するにはどうすればよいですか?

4

2 に答える 2

10

lc次のmapステートメントを使用して、小文字を使用します。

my @uniq_no_case = uniq map lc, @elements;

大文字と小文字が区別される理由は、ハッシュの重複排除特性に依存しているためです。これも大文字と小文字が区別されます。のコードは次のようになります。List::MoreUtils' uniquniq

sub uniq {
    my %seen = ();
    grep { not $seen{$_}++ } @_;
}

このサブを独自のコードで直接使用したい場合はlc、そこに組み込むことができます。

sub uniq_no_case {
    my %seen = ();
    grep { not $seen{$_}++ } map lc, @_;
}

これがどのように機能するかの説明:

@_サブルーチンへの引数が含まれ、それらはgrepステートメントに供給されます。コードブロックを通過したときにtrueを返す要素はすべて、grepステートメントによって返されます。コードブロックは、いくつかの細かい点で構成されています。

  • $seen{$_}++要素が最初に表示されたときに0を返します。値は引き続き1にインクリメントされますが、返された後(++$seen{$_}whoが最初にincし、次に戻るのとは対照的に)。
  • インクリメントの結果を否定することにより、最初のキーについてはtrueになり、後続のすべてのキーについてはfalseになります。したがって、リストは重複排除されます。
  • grepサブの最後のステートメントがリストを返すので、リストはサブによって返されます。
  • map lc, @_lcのすべての要素に関数を適用するだけ@_です。
于 2012-10-25T17:09:50.720 に答える
6

ハッシュを使用して、既に見た単語を追跡しますが、大文字/小文字の正規化も行います。

my %seen;
my @unique;
for my $w (@words) {
  next if $seen{lc($w)}++;
  push(@unique, $w);
}
# @unique has the unique words

これにより、元の単語の大文字と小文字が保持されることに注意してください。

更新: コメントに記載されているように、OP が何を必要としているかは明確ではありませんが、「等価関係」の下でリストから一意の代表者を選択するための一般的な手法を説明するために、この方法でソリューションを書きました。この場合、同値関係は word $ais equal to word $bif and only iflc($a) eq lc($b)です。

ほとんどの同値関係は、この方法で表現できます。つまり、関係は、if and only if と同等f()の分類子関数によって定義されます。たとえば、同じ長さの 2 つの単語が同等であると言いたい場合は、 になります。$a$bf($a) eq f($b)f()length()

これで、アルゴリズムをこのように記述した理由がわかるかもしれません。分類子関数は、元のリストの一部である値を生成しない場合があります。の場合、f = length単語を選択したいのですがf、の単語は数字です。

于 2012-10-25T17:11:36.363 に答える