Arrays 检查数组中的元素是否是另一个数组中元素的子字符串的有效方法
我有两个阵列:Arrays 检查数组中的元素是否是另一个数组中元素的子字符串的有效方法,arrays,perl,Arrays,Perl,我有两个阵列: @array1包含blah1到blah100 @array2包含名称:创建“blah1”通过名称:创建“blah100” 我需要检查@array1中的每个元素是否在@array2中,但是名称:creating部分正在妨碍 确保@array1中的所有元素都位于@array2中的最佳路径是什么 可能是在@array1与@array2之间循环时使用正则表达式进行匹配? 还有别的更快的方法吗 当其中一个数组中有嘈杂的字符串时,数组_diff、相交或唯一是否有效 或 也许可以操纵@arra
@array1
包含blah1
到blah100
@array2
包含名称:创建“blah1”
通过名称:创建“blah100”
@array1
中的每个元素是否在@array2
中,但是名称:creating
部分正在妨碍
确保@array1
中的所有元素都位于@array2
中的最佳路径是什么
可能是在@array1
与@array2
之间循环时使用正则表达式进行匹配?还有别的更快的方法吗 当其中一个数组中有嘈杂的字符串时,
数组_diff
、相交
或唯一
是否有效
或
也许可以操纵@array2,使其摆脱Name:为每个数据创建部分
哪条路更快
die if @array1 != @array2;
for (0..$#array1) {
die if $array2[$_] ne qq{Name: creating "$array1[$_]"};
}
或者如果名称部分是可变的
die if @array1 != @array2;
for (0..$#array1) {
die if $array2[$_] !~ /: creating "\Q$array1[$_]\E"$/;
}
我将使用相同的规则对两个数组进行排序,然后逐个进行比较
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);
不同之处在于创建了一个包含映射和模式的新列表。我将使用映射从第二个数组中筛选所需的部分,然后使用智能匹配操作符(~~)比较这两个部分:
在本例中,假设两个数组都已排序,如果不只是使用“sort”的话。示例数据
下面的前两行是问题的解决方案
请注意,现在可以安全地对@array1
和@check
进行排序,以防原始数组的顺序不一致。(排序@array
和@array2
只可能破坏可能已经存在的任何顺序,因为在@array2
中的值前面加了名称前缀)
my@check=map{m/:.*?(.*)/g}@array2;
我的$i=0;
if(@array1==@array2){
对于(;$i<@array1;$i++){
最后一个if$array1[$i]ne$check[$i];
}
}否则{
$i=-1;
}
如果($i==@array1){
打印“相同\n”;
}否则{
打印“不同的\n”;
}
请注意,只有当数组不相同时,这个较长的代码才更有效率。如果您通常希望数组的值相同,那么使用较长的代码没有任何好处
顺便说一句:这个正则表达式看起来很粗心,但根据OP,它正是我们想要的,特别是如果blah1、blah2等可能包含额外的双引号。如果我们确定没有名称包含引号,那么我们可以删除:.*.
,只需执行“(.\*)”
,这将更快。这应该是最快的,但与的相比,差距很小
编辑:
如果字符串的名称部分是变量:
die if @array1 != @array2;
my $i;
for my $e (@array1) {
die if $array2[$i++] !~ m/: creating "\Q$e\E"/;
}
您可以控制这些数组的创建吗?或者你从某处得到它们。你想要什么结果?布尔值表示“匹配”或“不匹配”是否足够,或者还需要什么?无法控制这些数组的创建@user4035@AdrainHHHarray1数据的“全部”(而不仅仅是少数)布尔值在array2@ealeon毫无疑问,没有其他方法,然后使用regexp逐元素比较它们。并检查它们的长度是否相等。如果它们已排序。否则就只能对它们进行排序。@Joseph Myers,OP没有具体说明他想要做什么,但1)他暗示如果它们不同,那就是错误。(“确保所有元素……”的最佳途径是什么,强调我的),以及2)如果需要更改,很容易确定需要更改的内容(例如,s/die/return 0/
)。@Joseph Myers,Re“如果我想在程序中使用它[…],我必须先重写它。”我是为OP写的,不是为你写的。正如我已经解释过的,您的更改将不符合OP规定的要求。如果您的需求与OP不同,并且需要一些帮助来调整代码,请告诉我。@Joseph Myers,已调整为忽略“名称”部分。@ikegami,谢谢,但不,我不需要任何帮助。我已经做了大约15年的perl黑客和软件包编写员,精通几乎所有版本,甚至MacPerl for MacOS8。我试图对社区有所帮助,其中包括那些无法理解如何将die代码调整为在其程序中工作的逻辑的人。(我大概100%肯定地怀疑Name与blah1和blah2一样不是一个文字值。)这是一个例子,只需列出您自己的排序规则和比较。请注意,“Name”不能像“blah1”和“blah2”那样被假定为文字值假设不是这样的解决方案几乎肯定是错误的。我的第一个建议的解决方案总是有效的。对于我的第二个解决方案,您有点正确。我在标量上下文中正确地比较了两个数组的长度,并正确地比较了足够数量的元素,以确定它们是否不相同。但是,仅将$i
与@array1
进行比较的快捷方式假定@array1
中存在数据。我将更新以处理@array1==0
的情况。请注意,OP上说“@array1
有数据”,所以事实上,我的两个解决方案都是正确的多么巧妙的把戏!我还在争论是否要走这条路线,因为如果arr2“只包含”arr1,这条路线就会通过,即arr2可以包含arr1中的内容以及更多内容代码>用于?我不认为这是必要的local$\u=$\ uu代码>是必需的,因为我不想更改@arr2!这里有详细的描述:
#!/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";
}
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";
}
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";
}
die if @array1 != @array2;
my $i;
for my $e (@array1) {
die if $array2[$i++] ne qq{Name: creating "$e"};
}
die if @array1 != @array2;
my $i;
for my $e (@array1) {
die if $array2[$i++] !~ m/: creating "\Q$e\E"/;
}