简体   繁体   中英

compare an array of string with another array of strings in perl

I want to compare an array of string with another array of strings; if it matches, print matched.

Example:

@array = ("R-ID 1.0001", "RA-ID 61.02154", "TCA-ID 49.021456","RCID 61.02154","RB-ID 61.02154");
@var = ("TCA-ID 49", "R-ID 1");

for (my $x = 0; $x <= 4; $x++)
{
  $array[$x] =~ /(.+?)\./;
  if( ($var[0] eq $1) or ($var[1] eq $1) )
  {
    print "\n deleted rows are :@array\n";
  }
  else
  {
    print "printed rows are : @array \n";
    push(@Matrix, \@array);
  }

Then I need to compare @var with the @array ; if it is matched, print the matched pattern.

Here the entire logic is in a hireartical for loop which gives a new @array in each iteration. so every time this logic is executed @array has different strings.

Then comes with @var it is user input field, this @var can be of any size. So in order to run the logic according to these constraints, I need to iterate the condition inside the if loop when the user input @var size is 3 for example.

So the goal is to match and delete the user input stings using the above mentioned logic. But unfortunately tis logic is not working. Could you please help me out in this issue.

The builtin grep keyword is a good place to start.

my $count = grep { $_ eq $var } @array;

This returns a count of items ( $_ ) in the array which are equal ( eq ) to $var .

If you needed case-insensitive matching, you could use lc (or in Perl 5.16 or above, fc ) to do that:

my $count = grep { lc($_) eq lc($var) } @array;

Now, a disadvantage to grep is that it is counting the matches. So after if finds the first match, it will keep on going until the end of the array. You don't seem to want that, but just want to know if any item in the array matches, in which case keeping on going might be slower than you need if it's a big array with thousands of elements.

So instead, use any from the List::Util module (which is bundled with Perl).

use List::Util qw( any );
my $matched = any { $_ eq $var } @array;

This will match as soon as it finds the first matching element, and skip searching the rest of the array.

Here is a couple of versions that allows multiple strings to be matched. Not clear what form $var takes when you want to store multiple, so assuming they are in an array @var for now.

The key point is this one is the use of the lookup hash to to the matching.

use strict;
use warnings;

my @var   = ("TCA-ID 49", "RA-ID 61");
my @array = ("R-ID 1", "RA-ID 61", "TCA-ID 49");

# create a lookup for the strings to match
my %lookup = map { $_ => 1} @var ;

for my $entry (@array)
{
    print "$entry\n" 
        if $lookup{$entry} ;
}

running gives

RA-ID 61
TCA-ID 49

Next, using a regular expression to do the matching

use strict;
use warnings;

my @var   = ("TCA-ID 49", "RA-ID 61");
my @array = ("R-ID 1", "RA-ID 61", "TCA-ID 49");

my $re = join "|", map { quotemeta } @var;

print "$_\n" for grep { /^($re)$/ } @array ;

output is the same

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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