2015-07-10 54 views
1

我有一個填充字符串的數組。我想檢查一個特定的字符串是否在這個數組中超過一次,然後打印錯誤警告。對數組中的匹配字符串進行Perl計數

我在List :: MoreUtils中使用了真正的方法來計算我的匹配。 在我的數組中,我有一些字符串,它們的子字符串與同一數組中的其他字符串相同。
因此,如果我檢查相同的字符串是否不止一次在數組中,我會得到我的錯誤警告,即使可能只是具有相同子字符串的另一個字符串。 我試圖通過添加字符串長度作爲模式來解決問題(所以字符串和長度必須相等,即彈出錯誤消息),但這也不起作用。
我的代碼看起來是這樣的:

use strict; 
use warnings; 
use List::MoreUtils 'true'; 

my @list = ("one", "two", "three", "onefour", "one"); 

foreach my $f (@list) { 

     my $length = length($f); 
     my $count = true { $length && "$f"} @list; 

      if($count > 1) { 
        print "Error with: ", $f, " counted ", $count, " times!\n"; 
       } 
     $count = 0; 
    } 

有了這個代碼,我沒有得到一個錯誤警告可言,即使「一」是兩次在數組中。如果我不包含長度作爲真正方法的模式,那麼字符串「one」將被計數三次。

+0

你是否只是「一」被報告爲愚蠢?例如。不是子字符串匹配? – Sobrique

回答

4

我不會爲此使用true - 它看起來像你試圖做的是'挑出'重複,並不關心子字符串。

my %seen; 
$seen{$_}++ for @list; 
print grep { $seen{$_} > 1 } @list; 

所以要複製你的測試:

my %count_of; 
$count_of{$_}++ for @list; 
foreach my $duplicate ( grep { $count_of{$_} > 1 } @list) { 
    print "Error: $duplicate was seen $count_of{$duplicate} time\n"; 
} 
+0

我不想「挑選」重複。如果數組中有重複項,我想打印一條錯誤消息,而不是更改數組/擦除重複項! – nieka

+0

這不會修改您的數組 - grep會創建一個您打印的「新」。我已經添加了一個片段,我_think_做你想要的東西? – Sobrique

+1

對不起,遲到的答案。你的回答非常好,解決了我的問題!非常感謝;) – nieka

1

你實際上是不匹配任何東西。我將調試輸出添加到您的代碼中。

my @list = ("one", "two", "three", "onefour", "one"); 

foreach my $f (@list) { 
    say "f: $f"; 
    my $length = length($f); 
    say "length: $length"; 
    say "true { $length && $f} $_: " . ($length && "$f") for @list; 
    my $count = true { $length && "$f" } @list; 
    say "count: $count"; 

    if ($count > 1) { 
     print "Error with: ", $f, " counted ", $count, " times!\n"; 
    } 
    $count = 0; 
} 

讓我們一起來看看:

f: one 
length: 3 
true { 3 && one} one: one 
true { 3 && one} two: one 
true { 3 && one} three: one 
true { 3 && one} onefour: one 
true { 3 && one} one: one 
count: 5 
Error with: one counted 5 times! 
f: two 
length: 3 
true { 3 && two} one: two 
true { 3 && two} two: two 
true { 3 && two} three: two 
true { 3 && two} onefour: two 
true { 3 && two} one: two 
count: 5 
Error with: two counted 5 times! 
f: three 
length: 5 
true { 5 && three} one: three 
true { 5 && three} two: three 
true { 5 && three} three: three 
true { 5 && three} onefour: three 
true { 5 && three} one: three 
count: 5 
Error with: three counted 5 times! 
f: onefour 
length: 7 
true { 7 && onefour} one: onefour 
true { 7 && onefour} two: onefour 
true { 7 && onefour} three: onefour 
true { 7 && onefour} onefour: onefour 
true { 7 && onefour} one: onefour 
count: 5 
Error with: onefour counted 5 times! 
f: one 
length: 3 
true { 3 && one} one: one 
true { 3 && one} two: one 
true { 3 && one} three: one 
true { 3 && one} onefour: one 
true { 3 && one} one: one 
count: 5 
Error with: one counted 5 times! 

所以,你總是有串$f,這是大於0,因此評價爲Perl的true的長度。那麼你有$f。這也是true,因爲所有不是空字符串的字符串('')都是真的。

使用true函數遍歷@list中的所有元素。該塊永遠是真實的。所以你總是得到@list中元素的數量。


如果您只想刪除雙重事件,則可以使用散列來計算它們。

my %count; 
$count{$_}++ for @list; 
my @unique = keys %count; # unsorted 
# see Sobrique's answer with grep for sorted the same way as before 

然後也有在List::MoreUtilsuniq

my @unique = uniq @list; 

如果你想知道每個元素,如果它是任何其他元素的子串,你可以使用Perl's builtin index,它發現某個字符串在另一字符串中的位置,以及grep

foreach my $f (@list) { 
    if (my @matches = grep { $_ ne $f && index($_, $f) > -1 } @list) { 
     warn "$f is a substr of: @matches"; # will auto-join on $, 
    } 
} 

__END__ 

one is a substr of: onefour at /code/scratch.pl line 91. 
one is a substr of: onefour at /code/scratch.pl line 91. 

當然,這當然不會得到因爲ne因素0和4都是「1」。請注意,如果根本沒有匹配,index返回-1


編輯your comment on Sobrique's answer

只得到警告,如果有重複的(或SUBSTR重複),簡單地計算他們。沒有任何修改發生在任何地方:

my @list = ("one", "two", "three", "onefour", "one"); 

my %count; 
$count{$_}++ for @list; 
warn sprintf 'Number of duplicates: %d', @list - keys %count if @list != keys %count; 

my $count_substr; 
foreach my $f (@list) { 
    $count_substr++ 
     if grep { $_ ne $f && index($_, $f) > -1 } @list; 
} 
warn sprintf 'Number of substring duplicates: %d', $count_substr if $count_substr; 
+0

一個更全面的答案。我認爲我們得出了類似的結論,認爲「真實」並不是真正正確的選擇。 – Sobrique

+0

謝謝@Sobrique。 :)你有沒有注意到我們的名字看起來很相似?那總是讓我感到疲憊。 – simbabque