我有两个数组:
@array1
包含blah1
到blah100
。@array2
包含Name: creating "blah1"
到Name: creating "blah100"
。我需要检查@array1
中的每个元素是否在@array2
中,但Name: creating
部分正在阻碍。
确保@array1
中的所有元素都在@array2
中的最佳途径是什么?
也许在使用@array1
对@array2
进行循环时使用正则表达式进行匹配?
还有另一种更快的方法吗?
当其中一个阵列中存在嘈杂的字符串时,array_diff
,intersect
或unique
是否正常工作?
OR
可能会操纵@ array2,以便它为每个数据摆脱Name: creating
部分?
哪种方式会更快?
答案 0 :(得分:4)
die if @array1 != @array2;
for (0..$#array1) {
die if $array2[$_] ne qq{Name: creating "$array1[$_]"};
}
或 Name 部分是变量,
die if @array1 != @array2;
for (0..$#array1) {
die if $array2[$_] !~ /: creating "\Q$array1[$_]\E"$/;
}
答案 1 :(得分:1)
我会使用相同的规则对两个数组进行排序,然后逐个进行比较。
use strict;
use warnings;
sub checkall{
my @array1 = @{shift};
my @array2 = @{shift};
my @sorted1 = sort{ $a <=> $b } @array1;
my @sorted2 = sort{ $a <=> $b } @array2;
if( $#sorted1 == $#sorted2){
for(0 .. $#sorted1)
{
#print $sorted1[$_] ."->". $sorted2[$_] ."\n"; #uncomment to see the comparison
return "doesn't match!" if not $sorted1[$_] eq $sorted2[$_];
}
return "ok!";
}else
{
return "not same size!";
}
}
my @array1 = (4,2,3,1);
my @array2 = (1,2,3,4);
print checkall(\@array1,\@array2);
更接近问题要求的另一个版本:
sub checkall{
my @array1 = @{shift};
my @array2 = @{shift};
my $aux;
my @sorted1 = sort ( map{ ($aux) = $_ =~ /Name\: creating \"(.*)\"/g } @array1 );
my @sorted2 = sort @array2;
if( $#sorted1 == $#sorted2){
for(0 .. $#sorted1)
{
#print $sorted1[$_] ."->". $sorted2[$_] ."\n"; #uncomment to see the comparison
return "doesn't match!" if not $sorted1[$_] eq $sorted2[$_];
}
return "ok!";
}else
{
return "not same size!";
}
}
不同之处在于创建了一个包含地图和模式的新列表。
答案 2 :(得分:1)
我使用map来过滤第二个数组中所需的部分,然后将它们与智能匹配运算符进行比较(~~):
#!/usr/bin/perl
use strict;
use warnings;
my @arr1 = qw(blah1 blah2 blah3);
my @arr2 = ('Name: creating "blah1"','Name: creating "blah2"','Name: creating "blah3"');
my @compare = map { local $_ = $_; s/^.+\: creating "([a-zA-Z0-9]+)"/$1/; $_ } @arr2;
if (@arr1 ~~ @compare){
print "all blahs there\n";
}
在这个例子中假设两个数组都已经排序,如果不是只使用“sort”。
答案 3 :(得分:1)
示例数据
my @array1 = qw(blah1 blah2);
my @array2 = split(';', 'Joe: creating "blah1";Bill: creating "blah2"');
以下前两行是您问题的解决方案
my @check = map { m/:.*?"(.*)"/g } @array2;
if (@array1 == @array2 && "@array1" eq "@check") {
# note that @array1 == @array2 is only done for efficiency;
# it would be sufficient to verify only that
# "@array1" eq "@check"
print "same\n";
} else {
print "different\n";
}
请注意,现在可以安全地对@array1
和@check
进行排序,以防原始数组的顺序不同。 (排序@array
和@array2
只会破坏可能已经存在的任何订单,因为@array2
中的值前缀为名称。)
my @check = map { m/:.*?"(.*)"/g } @array2;
my $i = 0;
if (@array1 == @array2) {
for (; $i < @array1; $i++) {
last if $array1[$i] ne $check[$i];
}
} else {
$i = -1;
}
if ($i == @array1) {
print "same\n";
} else {
print "different\n";
}
请注意,如果您的阵列不相同,则此较长的代码只会提高效率。如果通常情况下您希望数组的值相同,则使用较长的代码没有任何好处。
BTW:正则表达式看起来粗心,但根据OP,它正是我们想要的,特别是如果blah1,blah2等可能包含额外的双引号。如果我们确定没有名称包含引号,那么我们可以删除:.*?
并单独执行"(.\*)"
,这会更快。
答案 4 :(得分:1)