繁体   English   中英

查找与第二个数组的元素匹配的数组元素

[英]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";
}

我必须诚实。 我认为mapgrep都很烦人,如果你不熟悉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 / popshift / 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM