But for clarity you are probably best off with the nested loops and hash approach offered by rodion
sub test_regex { my @array1 = ( "test", "test2", "test2", "test3", "test4", "test4" + ); my @array2 = ( "test", "test", "test2.1", "test4.1", "test4.2", "t +est4.3" ); # Create a list of the items in array 1 separated by | # The reverse sort is used to keep the longer names to the front o +f # the list, in order to avoid matching 'test' when we could match +'test4' my $match_array1 = join('|',reverse sort @array1); # Using the 'x' option with regular expressions helps readability, + # even in simple cases like this my $regex = qr{ ^ ($match_array1) }x; my %found_one = (); foreach my $item2 (@array2) { next unless defined $item2; if ($item2 =~ /$regex/) { $found_one{$1}++; } } return keys %found_one; }
The results on my machine are:use strict; use warnings; use Benchmark qw(cmpthese); if (0) { print "regex: $_\n" for test_regex(); print "loop: $_\n" for test_loop(); exit; } cmpthese(1000,{ loop => \&test_loop, regex => \&test_regex, }); sub test_regex { my @array1 = ( "test", "test2", "test2", "test3", "test4", "test4" + ); my @array2 = ( "test", "test", "test2.1", "test4.1", "test4.2", "t +est4.3" ); # Create a list of the items in array 1 separated by | # The reverse sort is used to keep the longer names to the front o +f # the list, in order to avoid matching 'test' when we could match +'test4' my $match_array1 = join('|',reverse sort @array1); # Using the 'x' option with regular expressions helps readability, + # even in simple cases like this my $regex = qr{ ^ ($match_array1) }x; my %found_one = (); foreach my $item2 (@array2) { next unless defined $item2; if ($item2 =~ /$regex/) { $found_one{$1}++; } } return keys %found_one; } sub test_loop { my @array1 = ( "test", "test2", "test2", "test3", "test4", "test4" + ); my @array2 = ( "test", "test", "test2.1", "test4.1", "test4.2", "t +est4.3" ); my %found_one = (); foreach my $item1 (@array1) { foreach my $item2 (@array2) { next unless defined $item2; if (match_names($item1, $item2)) { $found_one{$item1}++; last; } } } return keys %found_one; } sub match_names { my ($x,$y) = @_; return 1 if ($y =~ /$x/); return; }
Rate loop regex loop 1136/s -- -60% regex 2857/s 151% --
In reply to Re: multiple matching in arrays
by imp
in thread multiple matching in arrays
by rsiedl
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |