如何遍历多个 Perl 数组

How to Iterate through multiple Perl arrays

我希望创建一个循环,使我能够使用更少的代码行来使用 Perl 更改设置文件。目前我的代码读取一个 XML 文件并找到一个设置 ID 并将该 ID 中的设置值替换为一个新的设置值。目前的请求涉及到对settings文件的大量修改,代码也很长。我在一个数组中设置了我的值,在一个数组中设置了我的设置 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 中做的事情吗?如果是这样,最有效的方法是什么?

以下代码示例演示了如何使用 %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);
}

参考:hash, hash operations

一个简单的例子

use warnings;
use strict;
...

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

我认为您不需要所有这些单独的 $matchSunDP1G1 等。假设两个数组始终具有相同的长度,并且它们的元素在相同的索引处成对需要。

语法 $#aryname 用于数组 @aryname 中的最后一个索引,而 ..range operator,因此您的示例的 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.

另一种方式,使用 zip from the core List::Util 模块:

#!/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]);

}