2010-10-12 86 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; 

这样的事情,当你不小心图案的哪个部分工作只要匹配就匹配。