0

im still beginner with perl , here im trying to loop over $struct->{'transferBatch'}->{'networkInfo'}; and its dump looks like :

$VAR1 = {
            'utcTimeOffsetInfo' => [
                                     {
                                       'utcTimeOffset' => '+0100',
                                       'utcTimeOffsetCode' => 0
                                     }
                                   ],
            'recEntityInfo' => [
                                 {
                                   'recEntityId' => '87.238.128.37',
                                   'recEntityType' => 2,
                                   'recEntityCode' => 0
                                 },
                                 {
                                   'recEntityCode' => 1,
                                   'recEntityType' => 2,
                                   'recEntityId' => '213.233.130.201'
                                 },
                                 {
                                   'recEntityId' => '353876999524',
                                   'recEntityCode' => 1,
                                   'recEntityType' => 1
                                 },
                                 {
                                   'recEntityCode' => 3,
                                   'recEntityType' => 1,
                                   'recEntityId' => '353876999523'
                                 }
                               ]
          };

i just want to get the recEntityCode where recEntityType = 2 and store it in veriable $recEntityCode_2 and same thing for recEntityType = 1 $recEntityCode_1 , only one value for each on of them just first catch then break out the loop

#!/usr/bin/perl -w

use strict;
use warnings;

use TAP3::Tap3edit;
use Data::Dumper;



printDir(".");
sub printDir{
opendir(DIR, $_[0]);
my @files;
my @dirs;
 (@files) = readdir(DIR);
 foreach my $file (@files) {
    if (-f $file and substr($file,0,2) eq "CD") {


     my $tap3 = TAP3::Tap3edit->new;

     my $tap_file = $file;
$tap3->decode($tap_file)  or  die $tap3->error; 

my $struct=$tap3->structure;

my $Tracker = $struct->{'transferBatch'};
if (defined $Tracker){



my $rectag = $struct->{'transferBatch'}->{'networkInfo'}->{'recEntityInfo'};

$count_1=0;
$count_2=0
foreach my $rectag1( @{$rectag} )
{
    if ($rectag1->{'recEntityType'} && int($rectag1->{'recEntityType'}) == 2){
      $var1_recEntityType = $rectag1->{'recEntityCode'}
      $count_1 = $count_1 + 1;
    }
    if ($rectag1->{'recEntityType'} && int($rectag1->{'recEntityType'}) == 1){
      $var1_recEntityType = $rectag1->{'recEntityCode'}
      $count_2 = $count_2 + 1;
    }
    if ($count_1 = 1 && $count_2 = 1)
    {
    break;
    }
}

print $recEntityCode_2;
print$recEntityCode_1;
$tap3->encode("$tap_file")  or  die $tap3->error; 

}
    }

 } 

 closedir(DIR);
}
15
  • There is no break statement in Perl. Also you are not showing us the full code, or you don't have use strict and use warnings. There might be other typos in your code. What is the output you are getting? Commented Nov 25, 2019 at 15:11
  • 2
    $count_1 = 1 is probably supposed to be $count_1 == 1, etc Commented Nov 25, 2019 at 15:30
  • 1
    No, the break statement (last) does not require use feature 'switch' or use v5.10 Commented Nov 25, 2019 at 15:33
  • 1
    You need to tag someone (@ikegami) for them to get notified if it's not tehir post to which you are replying. Commented Nov 26, 2019 at 4:19
  • 1
    print Dumper \$t; should have been print Dumper $t. That explains the extra `` in the output (which I removed). Commented Nov 26, 2019 at 4:19

2 Answers 2

2

I Don't know if there's another method for counter, but it Worked with me :

my $element;
$counter_rec2 = 0;
$counter_rec1 = 0;

foreach $element ( @{$struct->{'transferBatch'}->{'networkInfo'}->{'recEntityInfo'} } ) {

    if (defined $element->{recEntityType} && $element->{recEntityType}==2 && $counter_rec2 == 0 ) {
        $recEntityCode2=$element->{recEntityCode};
        $counter_rec2 = $counter_rec2 +1;
        print "recEntityCode: $recEntityCode2\n";
    }

    if (defined $element->{recEntityType} && $element->{recEntityType}==1 && $counter_rec1 == 0 ) {
        $counter_rec1 = $counter_rec1 +1;
        $recEntityCode1=$element->{recEntityCode};
        print "recEntityCode: $recEntityCode1\n";
    }

}

print "this is value for 2 $recEntityCode2\n";
print "this is value for 1 $recEntityCode1\n";
Sign up to request clarification or add additional context in comments.

Comments

2

Well, there're many solutions depending on what you exactly have and what you exactly want (TIMTOWTDI, you know). Do you know an exact number of entity types? Are you sure there's at least one array element for each of those entities?

The following code is rather dirty and proof-of-concept just to give you an idea, and it answers the literal question as it was asked (I assume your input hash is referenced as $r):

no strict;
no warnings;
use List::Util qw(first);

for my $type (1, 2) {
    ${qq|recEntityCode_$type|} = (first { $_->{recEntityType} == $type } $r->{recEntityInfo}->@*)->{recEntityCode};
}

print $recEntityCode_1 . "\n";
print $recEntityCode_2 . "\n";

For sure, I wouldn't use it. Much better way is to create a hash to store your results and not to declare separate variables for each of them:

use strict;
use warnings;
use List::Util qw(first);

my %recEntityCodes;

for my $type (1, 2) {
    $recEntityCodes{$type} = (first { $_->{recEntityType} == $type } $r->{recEntityInfo}->@*)->{recEntityCode};
}

print $recEntityCodes{1} . "\n";
print $recEntityCodes{2} . "\n";

Easy to see it is not optimal either, as we're walking the array from the start for each type (again, just to demonstrate one of possible solutions).

The simpliest solution I can invent out of my head is the following:


use strict;
use warnings;

my %recEntityCodes;

$recEntityCodes{$_->{recEntityType}} //= $_->{recEntityCode} for $r->{recEntityInfo}->@*;

print $recEntityCodes{1} . "\n";
print $recEntityCodes{2} . "\n";

Here we walk an array just once, but, on the other hand, we always walk the whole array.

Which one is the best is up to you. If you array is short enough you usually don't care and just take variant 3 as shortest code. If the array is large, either of variants 2 or 3 may be profitable depending on array properties. If the array is really huge, it worth optimizing further.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.