2010-10-12 82 views
2

我想要搜索數組中所有與另一個數組中的元素具有相同起始字符集的元素。要說清楚:如何從Perl數組中選擇某些元素?

@array = ("1a","9","3c"); 
@temp =("1","2","3"); 

我想只打印1a和3c。當我嘗試使用下面的程序就會打印出數組,而不是兩個我希望中的所有元素:

foreach $word (@temp) 
{ 
    if(grep /^$word/ , @array) 
    { 
     print $_; 
    } 
} 

任何見解將不勝感激。

+2

你應該接受一些你以前的問題的答案:) – 2010-10-12 14:38:11

+1

完成。不知道我必須這樣做。 – omgpython 2010-10-12 14:45:00

+0

我建議你用'my'聲明變量,例如'我的@array =(..)','foreach我的$ word(@temp){..}'並且啓用嚴格和警告 – 2010-10-12 17:08:26

回答

3

這個答案會做OP想要什麼,並防止任何重複從通過屏幕上打印使用散列查找。

#!/usr/bin/perl 

use strict; 
use warnings; 

my @array = ("1a","9","3c","3c"); 
my @temp =("1","2","3"); 

my %dups_hash; 

for my $w (@temp) { 
    my ($match) = grep /^$w/, @array; 

    # Need to check if $match is defined before doing the hash lookup. 
    # This suppresses error messages for uninitialized values; if defined($match) is 
    # false, we short circuit and continue in the loop. 
    if(defined($match) && !defined($dups_hash{$match})) { 
     print $match; 
    } 
} 
+0

完美的作品。謝謝 :) – omgpython 2010-10-12 15:42:44

1

如果你想匹配的元素成對,你可以這樣來做:

for my $i (0..$#array) { 
    print $array[$i], "\n" if $array[$i] =~ /^$temp[$i]/ 
} 

否則,你可以使用grep:

for my $i (0..$#array) { 
    print "$array[$i]\n" if grep /^$temp[$i]/, @array; 
} 
+2

我認爲這太嚴格了... OP只是說他想要打印的元素以另一個陣列中的任何元素開始。這實施了一對一的映射。 – 2010-10-12 14:49:51

+0

由於某種原因,我無法撤消我的-1 ...你能否幫我一個忙,並再次編輯這個文件,以便我可以撤消它? – 2010-10-12 15:07:29

+0

grep的第二個仍然沒有做OP所需要的。它將您使用的單詞打印到grep而不是數組中的值。 – Weegee 2010-10-12 15:24:35

0

當我嘗試使用以下 程序它打印出數組中的所有元素 而不是兩個我想要的 。

不,它不。正如所寫的,它不打印任何東西嚴格打開後,它打印「全局符號」$ temp「需要顯式包」。

修復了顯而易見的錯字並打開了警告,它將兩次打印「在打印中使用未初始化的值$ _」。

請不要浪費我們的時間,向我們展示代碼,要麼不編譯不會做你說的話。不要在此網站上重新輸入代碼 - 剪切並粘貼您正在使用的實際代碼。

解決您的問題將是這樣的:

#!/usr/bin/perl 

use strict; 
use warnings; 

my @array = ("1a","9","3c"); 
my @temp =("1","2","3"); 

foreach my $word (@temp) { 
    print grep /^$word/ , @array; 
} 

但也有可能做的更有效的方法。

+1

這可能會導致重複(如果'@ temp'有多個元素開始相同,因此可以在'@ array'中匹配每個元素)。 – 2010-10-12 14:54:52

+0

謝謝你的回答。我做了複製粘貼「實際代碼和輸出」。雖然我知道它是一個標準,但我並不嚴格使用。我只是使用perl來快速處理字符串,雖然我知道我應該使用strict。 – omgpython 2010-10-12 15:08:54

-1
map { print "$_\n" } grep { my $a = $_; grep {$a =~ /^$_/} @temp } @array 

基本上,外grep選擇用於其中1個或多個在@temp元件的內regex--即匹配的元件,它選擇中的元素,其與一個(或多個)開始的所有元素@temp

+0

umm..quick followup..What如果你想只打印第一場比賽? – omgpython 2010-10-12 15:29:18

-1

爲了避免空白行,如果grep的返回空列表:

#!/usr/bin/perl 
use strict; 
use warnings; 
use 5.10.1; 

my @array = qw(1a 9 3c 1g); 
my @temp =(1, 2, 3); 
foreach my $word(@temp) { 
    my @l = grep{/^$word/}@array; 
    say "@l" if @l; 
} 

輸出:

1a 1g 
3c 
+0

downvoter可以解釋爲什麼嗎? – Toto 2010-10-14 18:40:41

1

對於這類問題,關鍵是不掃描比你要陣列多。我認爲Knuth寫了一本關於這個的書。 :)通常情況下,我們會陷入這種情況,因爲我們與我們首先嚐試的東西密切接觸。

您可以從所有你想一次搜索,然後掃描陣列模式的構建一個正則表達式:

use Regexp::Assemble; 

my @array = qw(1a 9 3c); 
my @temp = qw(1 2 3); 

my $ra = Regexp::Assemble->new; 
$ra->add(@temp); 

my $pattern = $ra->re; 
print "pattern is [$pattern]\n"; 

print join ' ', grep /\A$pattern/ , @array; 

這樣的事情,當你不小心圖案的哪個部分工作只要匹配就匹配。