[英]Finding elements of an array that match elements of a second array
我有两个数组@uarts
和@txd
看起来像这样
@uarts = qw(uart_1 uart_10 uart_3 uart_9 );
@txd = qw(PIO_uart_1 PIO_2_uart_1 PIO_uart_3 PIO_uart_10 PIO_uart_5 PIO_uart_9 PIO_uart_7);
我想只从@txd
提取那些包含@txd
任何元素的@uarts
。 我为它编写的代码如下,但不起作用。
my @array;
for (my $i = 0 ; $i <= $#uarts ; $i++) {
@array = grep { $_ =~ /$uarts[$i]/ } (@txd);
print "@array\n";
}
我必须诚实。 我认为map
和grep
都很烦人,如果你不熟悉perl - steer clear。 它们并没有获得太多 - 它们看起来像是在降低代码的复杂性,但那是因为grep的循环是隐含的。 所以你所做的就是让你的代码更难以理解。
另外 - 我真的不喜欢for
循环的风格 - 它在perl中几乎总是多余的 - 在上面的例子中,你引用的唯一元素是当前的元素(如果你正在访问'next'或'previous',这是另一回事'元素)。
因此,展开它:
foreach my $uart ( @uarts ) {
foreach my $PIO ( @txd ) {
if ( $PIO =~ m/$uart/ ) {
print "$PIO matches $uart\n";
}
}
}
注意:这不会进行任何类型的唯一性测试,因此如果发生多个匹配,您将获得欺骗。
哦,打开use strict;
并use warnings;
。 你的数组声明是错误的。
my @uarts = qw ( uart_1 uart_10 uart_3 uart_9 );
my @txd = qw ( PIO_uart_1 PIO_2_uart_1 PIO_uart_3 PIO_uart_10
PIO_uart_5 PIO_uart_9PIO_uart_7
);
我也会指出 - 你已经在你的循环之外限制了@array
,这可能意味着想要保留它。 但是,然后通过分配grep
的输出来破坏每次迭代。
我建议你在循环中@array
,或者看看push
/ pop
和shift
/ unshift
作为添加和删除现有数组中元素的方法。
您的代码“按原样”运行。 你应该总是说“不工作”是什么意思。
我认为问题在于您的代码与您描述的完全一致 。 它找到“来自@txd
那些包含@txd
任何元素的@uarts
”,而我认为你需要那些以@uarts
任何字符串结尾的元素。
因为它代表了你的程序输出
PIO_uart_1 PIO_2_uart_1 PIO_uart_10
PIO_uart_10
PIO_uart_3
PIO_uart_9
因此,在检查uart_1
它会找到PIO_uart_10
因为前者是后者的子串 。 要查找以给定的uart字符串结尾的元素,您只需要向正则表达式添加行尾锚点,以便它成为
@array = grep { $_ =~ /$uarts[$i]$/ } (@txd)
这会将输出更改为
PIO_uart_1 PIO_2_uart_1
PIO_uart_10
PIO_uart_3
PIO_uart_9
我希望你想要的是什么?
但它可以写得更好一点。 除非你特别需要索引,否则最好循环遍历数组的内容 ,并且@array
不需要是一个全局变量(并且它可以更好地使用它),所以这对你有用
use strict;
use warnings;
my @uarts = qw(uart_1 uart_10 uart_3 uart_9 );
my @txd = qw(PIO_uart_1 PIO_2_uart_1 PIO_uart_3 PIO_uart_10 PIO_uart_5 PIO_uart_9 PIO_uart_7);
for my $uart ( @uarts ) {
my @matches = grep /$uart\z/, @txd;
print "@matches\n";
}
产量
PIO_uart_1 PIO_2_uart_1
PIO_uart_10
PIO_uart_3
PIO_uart_9
您只需更改@array = grep{$_=~ /$uarts[$i]/}(@txd);
即可修复代码@array = grep{$_=~ /$uarts[$i]/}(@txd);
进入@ push @array, grep{$_=~ /$uarts[$i]/}(@txd);
。
但是,如何做到这一点的理智而有效的方法是准备匹配的正则表达式,并在O(N+M)
而不是O(N*M)
。
use strict;
use warnings;
my @uarts = qw(uart_1 uart_10 uart_3 uart_9);
my @txd
= qw(PIO_uart_1 PIO_2_uart_1 PIO_uart_3 PIO_uart_10 PIO_uart_5 PIO_uart_9 PIO_uart_7);
my @array = do {
my $re = join '|', map quotemeta, @uarts;
$re = qr/$re/;
grep /$re/, @txd;
};
print "@array\n";
@uarts =(uart_1,uart_10,uart_3,uart_9 );
@txd =(PIO_uart_1,PIO_2_uart_1,PIO_uart_3,PIO_uart_10,PIO_uart_5,PIO_uart_9,PIO_uart_7);
my @array;
for(my $i=0;$i<=$#uarts;$i++ )
{
@array=grep{$_=~/$uarts[$i]/}(@uarts);
print "@array\n";
}
产量
uart_1 uart_10
uart_10
uart_3
uart_9
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.