Home > Enterprise >  How to Iterate through a Perl Array with Multiple Arrays
How to Iterate through a Perl Array with Multiple Arrays

Time:10-06

I am hoping to make a loop that allows me to use less lines of code to make changes to a settings file with Perl. Currently my code reads an XML file and locates a settings ID and replaces the setting value in that ID with a new one. The current request involves a lot of changes to the settings file and the code is very long. I have set my values in an array and my settings ID's in an array. Like this:

@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');

and run the following.

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]);

I would like to run these changes through a loop just using the array [0] - [3] until completed as I have to do this same set of 4 multiple times. I am not too familiar with looping arrays. Is this something I can do in Perl? If so, what would be the most efficient way to do so?

CodePudding user response:

Following code sample demonstrates how you could use %hash for alternation you try to achieve.

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);
}

Reference: hash, hash operations

CodePudding user response:

A simple take

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

I take it that you don't need all those individual $matchSunDP1G1 etc. It's assumed that the two arays always have the same length, and their elements are needed in pairs at same indices.

There are libraries that help with use of multiple arrays in parallel, and yet other probably more elegant ways to do this, but let's firts see how the above serves.

CodePudding user response:

Yet Another Way, using zip from the core List::Util module:

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

}
  • Related