2

我正在寻找一些帮助。

要求:

通过一些验证,我在一个数组中存储了以下类型的值。

@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'
        ];

条件 ingrep评估!$seen++来自 的名称@names是否在 中@dupl,并且$_仅在$seen为 0 时保留。否则1( true) 被评估并$_保留。

于 2012-06-01T07:42:15.923 回答
2

使用 Perl,每当您想从某个集合中获取唯一值时,请考虑如何使用散列来帮助您自动折叠重复项,或者至少帮助您记住您已经看到的值。例如,请参阅如何从两个哈希中获取唯一键?在 Perl FAQ 的第 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'其值为 all [ 'rajesh', 'ram', 'peter' ]。以这种方式构建它意味着无论我们首先遇到哪个名称,我们都可以获得完整的名称集。

另请注意,您可以在一次调用中堆叠多组名称,如

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 回答