2012-06-01 92 views
2

我正在尋找一個senario中的幫助。根據自定義重複值從數組中刪除條目

要求:

通過一些驗證,我已經strored以下在一個陣列種值。

@array_name = ("Rajesh","Raju","Ram","John","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; 

任何最好的方式來實現這一目標?

+0

什麼是您的示例程序與您的預期產出呢? – flesk

回答

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條件計算!$seen++如果@names的名稱在@dupl中,並且只有當$seen爲0時才保留$_。否則,1true)被評估並且01保持。

2

使用Perl,無論何時您想要某些集合中的唯一值,請考慮如何使用哈希來幫助您自動摺疊重複項,或至少幫助您記住已經看到的值。例如,請參見Perl FAQ的第4部分中的How can I get the unique keys from two hashes?

你的情況有點棘手,因爲你有一組可互換的名字,所以你必須記錄這些信息。

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

底部的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; 

輸出:

Rajesh 
Raju 
John