如何遍历多个Perl数组



我希望创建一个循环,使我能够使用更少的代码行来使用Perl更改设置文件。目前,我的代码读取一个XML文件,找到一个设置ID,并用一个新ID替换该ID中的设置值。当前请求涉及对设置文件的大量更改,并且代码非常长。我在数组中设置了值我的设置ID也在数组中。这样的:

@GreetGoalDP1 = (3, 5, 7, 10);
@GreetSIDSunDP1 = ('//xsd:Settings/xsd:Setting[@SID="7012"]/xsd:Value', 
'//xsd:Settings/xsd:Setting[@SID="7013"]/xsd:Value', 
'//xsd:Settings/xsd:Setting[@SID="7014"]/xsd:Value', 
'//xsd:Settings/xsd:Setting[@SID="7015"]/xsd:Value');

,然后运行如下命令

my($matchSunDP1G1) = $xpc->findnodes($GreetSIDSunDP1[0]);
$matchSunDP1G1->removeChildNodes();
$matchSunDP1G1->appendText($GreetGoalDP1[0]);
#GreetB
my($matchSunDP1G2) = $xpc->findnodes($GreetSIDSunDP1[1]);
$matchSunDP1G2->removeChildNodes();
$matchSunDP1G2->appendText($GreetGoalDP1[1]);
#GreetC
my($matchSunDP1G3) = $xpc->findnodes($GreetSIDSunDP1[2]);
$matchSunDP1G3->removeChildNodes();
$matchSunDP1G3->appendText($GreetGoalDP1[2]);
#GreetD
my($matchSunDP1G4) = $xpc->findnodes($GreetSIDSunDP1[3]);
$matchSunDP1G4->removeChildNodes();
$matchSunDP1G4->appendText($GreetGoalDP1[3]);

我想通过循环运行这些变化,只是使用数组[0]-[3],直到完成,因为我必须做同样的一组4多次。我对循环数组不太熟悉。这是我可以在Perl中做的吗?如果是这样,最有效的方法是什么?

一个简单的例子

use warnings;
use strict;
...
for my $i (0..$#GreetGoalDP1) {
my ($matchSunDP1G) = $xpc->findnodes( $GreetSIDSunDP1[$i] );
$matchSunDP1G->removeChildNodes();
$matchSunDP1G->appendText( $GreetGoalDP1[$i] );
}

我认为你不需要所有这些单独的$matchSunDP1G1等。假设这两个数组的长度总是相同的,并且它们的元素需要成对地位于相同的下标处。

语法$#aryname用于数组@aryname中的最后一个索引,..是范围操作符,因此您的示例中的0 .. $#GreetGoalDP1是列表0,1,2,3

还有一些库可以帮助并行使用多个数组,当事情变得更混乱或更复杂时,这些库特别有用。使用迭代器

的示例
use List::MoreUtils qw(each_array);
my $it = each_array @GreetSIDSunDP1, @GreetGoalDP1;
while ( my ($sidsun, $goal) = $it->() ) {
my ($matchSunDP1G) = $xpc->findnodes($sidsun);
$matchSunDP1G -> removeChildNodes();
$matchSunDP1G -> appendText( $goal );
}

如果两个列表的大小不均匀,迭代器继续遍历长列表的长度。当较短的那个耗尽后,它的潜在值为undef

下面的代码示例演示了如何使用%hash来实现您尝试实现的更改。

my %hash = (
3   => '//xsd:Settings/xsd:Setting[@SID="7012"]/xsd:Value',
5   => '//xsd:Settings/xsd:Setting[@SID="7013"]/xsd:Value',
7   => '//xsd:Settings/xsd:Setting[@SID="7014"]/xsd:Value',
10  => '//xsd:Settings/xsd:Setting[@SID="7015"]/xsd:Value')
);
while( my($k,$v) = each %hash ) {
my $match = $xpc->findnodes($v);
$match->removeChildNodes();
$match->appendText($k);
}

参考:哈希,哈希操作

另一种方法,使用核心List::Util模块中的zip:

#!/usr/bin/env perl
use warnings;
use strict;
use List::Util qw/zip/;
...;
my @GreetGoalDP1 = (3, 5, 7, 10);
my @GreetSIDSunDP1 = ('//xsd:Settings/xsd:Setting[@SID="7012"]/xsd:Value', 
'//xsd:Settings/xsd:Setting[@SID="7013"]/xsd:Value', 
'//xsd:Settings/xsd:Setting[@SID="7014"]/xsd:Value', 
'//xsd:Settings/xsd:Setting[@SID="7015"]/xsd:Value');
foreach my $pair (zip @GreetSIDSunDP1, @GreetGoalDP1) {
my ($matchSunDP1G1) = $xpc->findnodes($pair->[0]);
$matchSunDP1G1->removeChildNodes();
$matchSunDP1G1->appendText($pair->[1]);
}

最新更新