2014-09-04 74 views
2

我知道如何避免一維數組中的重複。如何避免數組數組中的重複值?

但是,我有一個數組數組,它​​的兩行可能會保存具有不同引用但數值相同的數組。我試過這個:

sub unique { 
    my %seen; 
    grep !$seen{join('',$_)}++, @_ 
} 

my @aa = ( ["1","2","3"],["1","2","3"],["1","2","4"]); 
my @bb = unique(@aa); 
print $_ for (@bb); 

它應該刪除兩個「123」陣列中的一個,但它不。可能是因爲$ _擁有一個引用而不是可以加入的數組?當然,我可以循環訪問$ _參考數組並將所有值連接起來,然後將其用作%可見哈希的關鍵字。

但我懷疑有Perl中的一個非常優雅的解決方案,我還不知道的...

回答

5

要解決你的幼稚的做法,你應該取消引用兩個地方的數組引用:當序列化和時打印:

# Assumes the elements don't contain the value of $; (0x1C by default) 
sub unique { 
    my %seen; 
    grep ! $seen{ join $;, @$_ }++, @_ 
} 

my @aa = ( ["1","2","3"],["1","2","3"],["1","2","4"]); 
my @bb = unique(@aa); 
print "@$_\n" for (@bb); 

這仍然可能會給出錯誤的輸出,想象[ "1\x{1C}2", 3 ]。如果您的數據可能包含此類字符串,則需要更復雜的字符串化。幸運的是,Perl已經有一種序列化數組引用的方法:Data::Dumper

use Data::Dumper; 

sub unique { 
    my %seen; 
    grep ! $seen{ Dumper $_ }++, @_ 
} 
+0

很好用。我將使用@ $ _方法,因爲我的真實數據結構不允許像例子那樣的重複。請問,@ $ _實際上做了什麼?數組前的@是否總是返回數組本身? – jackthehipster 2014-09-04 12:33:17

+0

@jackthehipster:是的。在解引用更復雜的結構時,可能需要花括號:'@ {$ hash {key}}'。 – choroba 2014-09-04 12:58:46

+2

通過'$;'連接或者甚至單個空間似乎是最優的。 – 2014-09-04 12:59:50