Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Accessing Array Data

Status
Not open for further replies.

Perlnew

IS-IT--Management
Oct 3, 2014
3
IT
Hi guys, I have finally put together a small script that when implemented into a larger context will read data from a flat file and processed from output to Excel using Excel::Writer::XLSX. In the meantime, I am having difficulty accessing the data from the Array of Arrays. I trying to split the colon delimited data, however, the output is incorrect. I have stored each line of data using the $save scalar that concatenates each line from the foreach loop and pushes the results into an array. The data structure is provided as can be seen. To make a long story short, I would like to access each line of data and each individual data element. I am able to output correctly, however, I do not know how to repopulate the array to be accessed later on for further processing. Please note that I am a beginner.

Here is the code:

#!C:\Perl64\bin\perl.exe


use strict;
use warnings;
use Data::Dumper;





my %AG = (
GAHD => [ {
NAME => 'K. Long',
POSITION => 'SENIOR OFFICER',
GRADE => 'P5',
COUNTRY=>'ITALY',
PWD=>'Y',
DATE_OF_BIRTH=>'4/12/1944',
AGE => 45,
FEMALE=>'*',
VACANT=>'YELLOW'

},
{
NAME => 'J. Buber',
POSITION => 'CHIEF',
GRADE => 'D1',
COUNTRY=>'ITALY',
PWD=>'Y',
DATE_OF_BIRTH=>'4/12/1944',
AGE => 45,
FEMALE=>'*',
VACANT=>'YELLOW'
},
{
NAME => 'M. Amsi',
POSITION => 'SENIOR ANIMAL HEALTH OFFICER',
GRADE => 'P5',
COUNTRY=>'ITALY',
PWD=>'Y',
DATE_OF_BIRTH=>'4/12/1944',
AGE => 45,
FEMALE=>'*',
VACANT=>'YELLOW'
},
{
NAME => 'E. Xenu',
POSITION => 'SENIOR OFFICER',
GRADE => 'P5',
COUNTRY=>'ITALY',
PWD=>'Y',
DATE_OF_BIRTH=>'4/12/1944',
AGE => 45,
FEMALE=>'*',
VACANT=>'YELLOW'
},
],
GAGD => [
{
NAME => 'P. Cheru',
POSITION => 'ANIMAL PRODUCTION OFFICER',
GRADE => 'P4',
COUNTRY=>'ITALY',
PWD=>'Y',
DATE_OF_BIRTH=>'4/12/1944',
AGE => 45,
FEMALE=>'*',
VACANT=>'YELLOW'
},
{
NAME => 'B. Burns',
POSITION => 'ANIMAL PRODUCTION OFFICER',
GRADE => 'P4',
COUNTRY=>'ITALY',
PWD=>'Y',
DATE_OF_BIRTH=>'4/12/1944',
AGE => 45,
FEMALE=>'*',
VACANT=>'YELLOW'
},
{
NAME => 'R. Mung',
POSITION => 'ANIMAL PRODUCTION OFFICER',
GRADE => 'P4',
COUNTRY=>'ITALY',
PWD=>'Y',
DATE_OF_BIRTH=>'4/12/1944',
AGE => 45,
FEMALE=>'*',
VACANT=>'YELLOW'
},
{
NAME => 'B. Scherf',
POSITION => 'ANIMAL PRODUCTION OFFICER',
GRADE => 'P4',
COUNTRY=>'ITALY',
PWD=>'Y',
DATE_OF_BIRTH=>'4/12/1944',
AGE => 45,
FEMALE=>'*',
VACANT=>'YELLOW'

},
{
NAME => 'I. Hoffmann',
POSITION => 'CHIEF',
GRADE => 'P5',
AGE => 45,
FEMALE=>'*',
VACANT=>'YELLOW',
COUNTRY=>'ITALY',
PWD=>'Y',
DATE_OF_BIRTH=>'4/12/1944',
}
]);


my %positions;
my $counts = 0;
my %grades;
my $rec;
my @new2;
my $count=0;
my $c;
my $save;

for my $division (keys %AG) {
print "**$division**\n";

my %group;
my %group2;
for my $person (@{ $AG{$division} }) {

my $position = join ':', @{ $person }{qw{GRADE POSITION}};


push @{ $group{$position} },$rec=[$person->{NAME},$person->{COUNTRY},
$person->{DATE_OF_BIRTH},$person->{AGE},$person->{FEMALE},$person->{VACANT},$person->{PWD}]



}

for my $position ( sort { substr($a, 0, 1) cmp substr($b, 0, 1) || substr($b, 0, 2) cmp substr($a, 0, 2) } keys %group) {


$position =~ /(\w\d)\W(.*)/g;


my $pos=$1;
my $title=$2;
my $c=scalar @{ $group{$position} };

$save.=[$c.':'.$pos.':'.$title];

print scalar @{ $group{$position} }.":".$pos.':'.$title.':';


foreach my $key ( @{ $group{$position} }) {


print join ":",$key->[0],$key->[1],$key->[2],$key->[3],$key->[4],$key->[5],$key->[6],"\n";

$save.=[':'.$key->[0].':'.$key->[1].':'.$key->[2].':'.$key->[3].':'.$key->[4].':'.$key->[5].':'.$key->[6]."\n"];

}






}


# print Dumper @new2;

# exit;

push(@new2,$save);

}


foreach my $l_output (@new2) {

my($a,$b,$c,$e,$f,$g,$h,$i) = split (/:/,$l_output);

print join " ",$a,$b,$c,$e,$f,$g,$h,$i,"\n";

}


Output

**GAGD**
1:p5:CHIEF:I. Hoffmann:ITALY:4/12/1944:45:*:YELLOW:Y:
4:p4:ANIMAL PRODUCTION OFFICER:p. Cheru:ITALY:4/12/1944:45:*:YELLOW:Y:
B. Burns:ITALY:4/12/1944:45:*:YELLOW:Y:
R. Mung:ITALY:4/12/1944:45:*:YELLOW:Y:
B. Scherf:ITALY:4/12/1944:45:*:YELLOW:Y:
**GAHD**
1:D1:CHIEF:J. Buber:ITALY:4/12/1944:45:*:YELLOW:Y:
2:p5:SENIOR OFFICER:K. Long:ITALY:4/12/1944:45:*:YELLOW:Y:
E. Xenu:ITALY:4/12/1944:45:*:YELLOW:Y:
1:p5:SENIOR ANIMAL HEALTH OFFICER:M. Amsi:ITALY:4/12/1944:45:*:YELLOW:Y:
ARRAY(0x2f90db8)ARRAY(0x2f90db8)ARRAY(0x2f90e00)ARRAY(0x2f90e00)ARRAY(0x2f90de8)ARRAY(0x2f90410)ARRAY(0x2f90e00)
ARRAY(0x2f90db8)ARRAY(0x2f90db8)ARRAY(0x2f90e00)ARRAY(0x2f90e00)ARRAY(0x2f90de8)ARRAY(0x2f90410)ARRAY(0x2f90e00)ARRAY(0x2f90cc8)ARRAY(0x2f90cc8)ARRAY(0x2f90cb0)ARRAY(0x2f90cb0)ARRAY(0x2f8edf8)ARRAY(0x2f90cc8)ARRAY(0x2f90cc8)
 
Hmm.. I'm having a hard time tracking what you're exactly looking for as well. What are you looking for where all the "ARRAY(0x...)" output is? This should mostly replicate your output. I do notice one difference though -- the positions are sorted in a different order in at least one case. That should be fairly easily fixable though.

Code:
foreach my $division (sort keys %AG) {
	print "**$division**\n";
	my %order;
	foreach my $record (@{$AG{$division}}) {
		push @{$order{$record->{GRADE}}{$record->{POSITION}}}, $record;
	}
	
	foreach my $grade (sort { substr($a, 0, 1) cmp substr($b, 0, 1) || substr($b, 0, 2) cmp substr($a, 0, 2)} keys %order) {
		foreach my $position (sort keys %{$order{$grade}}) {
			print join(':', scalar @{$order{$grade}{$position}}, $grade, $position, '');
			
			foreach my $record (@{$order{$grade}{$position}}) {
				print join(':', map {$record->{$_}} qw/NAME COUNTRY DATE_OF_BIRTH AGE FEMALE VACANT PWD/), "\n";
			}
		}
	}
}

Which gives the following output:
Code:
**GAGD**
1:P5:CHIEF:I. Hoffmann:ITALY:4/12/1944:45:*:YELLOW:Y
4:P4:ANIMAL PRODUCTION OFFICER:P. Cheru:ITALY:4/12/1944:45:*:YELLOW:Y
B. Burns:ITALY:4/12/1944:45:*:YELLOW:Y
R. Mung:ITALY:4/12/1944:45:*:YELLOW:Y
B. Scherf:ITALY:4/12/1944:45:*:YELLOW:Y
**GAHD**
1:D1:CHIEF:J. Buber:ITALY:4/12/1944:45:*:YELLOW:Y
1:P5:SENIOR ANIMAL HEALTH OFFICER:M. Amsi:ITALY:4/12/1944:45:*:YELLOW:Y
2:P5:SENIOR OFFICER:K. Long:ITALY:4/12/1944:45:*:YELLOW:Y
E. Xenu:ITALY:4/12/1944:45:*:YELLOW:Y
 
This is much better, however, how do I a grow another data structure with the sorted output? In other words, I would like to take each line of data and tested against other conditions element by element afterwards, that is the data in between the colons as I was trying to do in the last foreach loop above. By reapplying some of my old code to store the output, I still get incomplete output. See below code.

What am I doing wrong. I simply would like to access each line of data and process whether the field has or does not have data.

Many thanks thus far.


my $save;
my @array;
foreach my $division (sort keys %AG) {
print "**$division**\n";
my %order;
foreach my $record (@{$AG{$division}}) {
push @{$order{$record->{GRADE}}{$record->{POSITION}}}, $record;
}

foreach my $grade (sort { substr($a, 0, 1) cmp substr($b, 0, 1) || substr($b, 0, 2) cmp substr($a, 0, 2)} keys %order) {
foreach my $position (sort keys %{$order{$grade}}) {
print join(':', scalar @{$order{$grade}{$position}}, $grade, $position,'');

$save.=join(':', scalar @{$order{$grade}{$position}}, $grade, $position,'');

foreach my $record (@{$order{$grade}{$position}}) {
print join(':', map {$record->{$_}} qw/NAME COUNTRY DATE_OF_BIRTH AGE FEMALE VACANT PWD/), "\n";

$save.= join(':', map {$record->{$_}} qw/NAME COUNTRY DATE_OF_BIRTH AGE FEMALE VACANT PWD/). "\n";

}
}

}


}

push (@array,$save);

#print Dumper @array;


foreach my $line (@array) {

my($count,$grade,$position,$name,$country,$date,$age,$female,$vacant,$pwd) = split(/:/,$line);

# I will need to perform tests against each data element afterwards which is not a problem.
# Eg. If ($grade eq 'P5) {... do something here,etc.)

print join "||",$count,$grade,$position,$name,$country,$date,$age,$female,$vacant,$pwd,"\n";

}

New Output

1||P5||CHIEF||I. Hoffmann||ITALY||4/12/1944||45||*||YELLOW||Y
4|| This line is incomplete and the rest does not output.


 
With the exception of the number of records for each grade/position combination (the first field being output) nothing is being calculated there. Is there a reason that you need to join all the fields together, split them back up, join them back together (with a different field delimiter) and print them? Couldn't the processing be done on the first pass through the data (the %AG data structure)?

If not, could you iterate over the data again and do any comparisons you need to do?
 
Also, here's what I think you're asking for:
Code:
my @saved;

foreach my $division (sort keys %AG) {
	print "**$division**\n";
	my %order;
	foreach my $record (@{$AG{$division}}) {
		push @{$order{$record->{GRADE}}{$record->{POSITION}}}, $record;
	}
	
	foreach my $grade (sort { substr($a, 0, 1) cmp substr($b, 0, 1) || substr($b, 0, 2) cmp substr($a, 0, 2)} keys %order) {
		foreach my $position (sort keys %{$order{$grade}}) {
			print join(':', scalar @{$order{$grade}{$position}}, $grade, $position, '');
			
			foreach my $record (@{$order{$grade}{$position}}) {
				print join(':', map {$record->{$_}} qw/NAME COUNTRY DATE_OF_BIRTH AGE FEMALE VACANT PWD/), "\n";
				push @saved, join(':', scalar @{$order{$grade}{$position}}, $grade, $position, map {$record->{$_}} qw/NAME COUNTRY DATE_OF_BIRTH AGE FEMALE VACANT PWD/);
			}
		}
	}
}

foreach my $line (@saved) {
	# Do stuff -- split, comparisons, etc.
}
 
Many thanks rharsh for your invaluable assistance.
[thumbsup2]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top