Perl 基于自定义重复值从数组中删除条目

Perl 基于自定义重复值从数组中删除条目,perl,Perl,我在一个塞纳里奥寻找帮助 要求: 通过一些验证,我在一个数组中选择了以下类型的值 @array_name = ("Rajesh","Raju","Ram","John","peter"); 现在我从一些背景中知道Rajesh、Ram、peter是重复条目,因此我希望我的输出是: @array_name = ("Rajesh","Raju","John"); # or @array_name = ("Ram","Raju","John"); # or @array_name = ("pete

我在一个塞纳里奥寻找帮助

要求:

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

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

实现这一点的最佳方法是什么?

如果您使用的是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'
        ];
Rajesh Raju John
grep中的条件计算$seen++如果@names中的名称在@dupl中,并且仅当$seen为0时才保留$。否则,将计算1 true并保留$。

如果您使用的是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'
        ];
Rajesh Raju John
grep中的条件计算$seen++如果@names中的名称在@dupl中,并且仅当$seen为0时才保留$。否则,将计算1 true并保留$。

使用Perl,每当您需要某个集合中的唯一值时,请考虑如何使用哈希来帮助您自动折叠重复项,或者至少帮助您记住已看到的值。例如,请参见Perl常见问题解答的第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]”。以这种方式构建它意味着,无论我们首先遇到哪个名称,我们都可以获得完整的名称集

还请注意,您可以在一个调用中堆叠多组名称,如中所示

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;
}
底部的位是一种常用的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;
输出:

$VAR1 = [
          'Rajesh',
          'Raju',
          'John'
        ];
Rajesh Raju John
使用Perl,每当您希望从某个集合中获得唯一值时,请考虑如何使用哈希来帮助您自动折叠重复项,或者至少帮助您记住已经看到的值。例如,请参见Perl常见问题解答的第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]”。以这种方式构建它意味着,无论我们首先遇到哪个名称,我们都可以获得完整的名称集

还请注意,您可以在一个调用中堆叠多组名称,如中所示

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;
}
底部的位是一种常用的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;
输出:

$VAR1 = [
          'Rajesh',
          'Raju',
          'John'
        ];
Rajesh Raju John
示例程序与预期输出有什么关系?示例程序与预期输出有什么关系?