加快foreach循环中的perl哈希和更好的算法
我有两个哈希->加快foreach循环中的perl哈希和更好的算法,perl,hash,foreach,Perl,Hash,Foreach,我有两个哈希->%a和%b。 散列%a来自temp.txt my %a = map{ my $short = substr($_,12); $count++ => {$short => $_}; } @a; my %b = map { $_ => $_; } @b; %a = ( '1' => {'We go lunch' => 'We go lunch 9 pm'}, '2' => {'We go break'
%a
和%b
。
散列%a
来自temp.txt
my %a = map{
my $short = substr($_,12);
$count++ => {$short => $_};
} @a;
my %b = map {
$_ => $_;
} @b;
%a = (
'1' => {'We go lunch' => 'We go lunch 9 pm'},
'2' => {'We go break' => 'We go break 8 pm'},
'3' => {'We go lunchy' => 'We go lunchy 8 pm'}
);
%b = (
'We go lunch' => 'We go lunch',
'We go break' => 'We go break',
'We go lunchy' => 'We go lunchy'
);
foreach my $key (keys %a){
foreach my $key2 (keys %{$a{$key}}){
if(exists $b{$key2}){
delete $a{$key}{$key2};
delete $a{$key};
}
}
}
my @another;
foreach my $key ( sort {$a<=>$b} keys %a) {
foreach my $key2 (keys %{$a{$key}}){
$another[$count] = $a{$key}{$key2};
$count++;
}
}
但它仍然不起作用。我很困惑,因此在%a中出现了这个散列,并从@b中生成了散列%b,只是为了去掉@a中@b的每个实例值。结果是奇怪的杂烩。lol这里有一些未知的东西-例如,
%b
是如何构建的。
除此之外,还有一些观察:
您应该使用另一个数组,而不是%a
:
my @c = map{
{ "".substr($_,12) => $_}
} @a;
如果您已经定义了%b
,您可以通过以下方式进一步优化它:
my @another = grep !exists $b{ substr($_,12) }, @a;
希望这有帮助
另外,不要忘了总是严格使用代码代码>和使用警告代码>在程序的开头
解释:
您的代码将所有内容放入%a
,遍历它并消除不应该存在的内容。
我认为您可以简单地grep
并在数组中只保留所需的结果
优化后的代码应为:
use strict;
use warning;
my %b = (
'We go lunch' => 'We go lunch',
'We go break' => 'We go break',
'We go lunch' => 'We go lunch'
);
#add code that initially fills @a
my @another = grep { !exists $b{ substr($_,12) } } @a;
看来你很困惑。首先,substr$\u12
返回字符串中第12位之后的所有字符,因此不会创建您所说的数据结构。其次,您使用散列的散列%a
作为数组数组,因为键是序列中没有空格的整数,并且存储的值是一个简单的字符串对
对我们来说,最大的问题是你没有解释你的目标
看起来是这样的:您希望最后得到一个数组@另一个,该数组包含temp.txt
中的所有行,这些行不以@b
中的任何字符串开头。是这样吗
我将通过从数组@b
构建一个正则表达式,并在读取文件时检查文件中的每一行来实现
这个程序演示了。我已将数组@b
重命名为@exclude
,因为前者对于变量来说是一个糟糕的名称。正则表达式是通过在数组的每个元素前面加上^
来构建的,以将正则表达式锚定在字符串的开头,并在\b
后面加上\b
来强制设置单词边界(例如,sunch
与sunchy
不匹配)。然后使用|
交替运算符将所有元素连接在一起,生成一个正则表达式,该正则表达式匹配以@exclude
中的任何行开头的字符串
在这之后,只需通读文件,对照正则表达式检查每一行,然后将不匹配的行推到另一行
请注意,目前程序从数据
文件句柄读取数据,以便在源代码中包含一些测试数据。您应该通过取消注释open
行,并删除行my$fh=*DATA
来更改它
使用严格;
使用警告;
#打开我的$fh,'为什么要设置%a两次?原因是在“以前的解决方法”下,而不是它不是。上面说你是从@b中获得%b,但你不是。(好的,您可以,但您已完成擦除所有工作。)哈希%b未被擦除。我只删除了hash%aI在这之前做了这个grep,但没有用,因为@a和@b(以前的代码)不是一个字符接一个字符的,所以@other中的所有内容都是未定义的。也许我的例子不对。我现在改了。
use strict;
use warning;
my %b = (
'We go lunch' => 'We go lunch',
'We go break' => 'We go break',
'We go lunch' => 'We go lunch'
);
#add code that initially fills @a
my @another = grep { !exists $b{ substr($_,12) } } @a;