perl array question

peterchan75

Supremacy Member
Joined
Apr 26, 2003
Messages
6,719
Reaction score
529
Hi All,

I have a 2 dimensional array and the second column has mm/dd/yyyy format date. The code below change the date to yyyymmdd format and sort the array by date in ascending order and store the result to array2 and convert the date from yyyymmdd back to mm/dd/yyyy in array2.

Code:
for (my $i=0;$i<=$#array1;$i++) { #Convert date from MM/DD/YYYY to YYYYMMDD
	my @mmddyyyy = split('/',$array1[$i][1]);
	$array1[$i][1] = int($mmddyyyy[2])*10000+int($mmddyyyy[0])*100+int($mmddyyyy[1])*1;
}

my @array2 = sort { $a->[1] <=> $b->[1] } @array1;

for (my $i=0;$i<=$#array2;$i++) { #Convert date from YYYYMMDD to MM/DD/YYYY
	$array2[$i][1] =  substr($array2[$i][1],4,2) . '/' . substr($array2[$i][1],6,2) . '/' . substr($array2[$i][1],0,4);
}

I do a print the first row and second column of array1 and I get back the old date format of mm/dd/yyyy.

Why does column 2 of array1 revert back to the old data ?
 

davidktw

Arch-Supremacy Member
Joined
Apr 15, 2010
Messages
13,547
Reaction score
1,301
Hi All,

I have a 2 dimensional array and the second column has mm/dd/yyyy format date. The code below change the date to yyyymmdd format and sort the array by date in ascending order and store the result to array2 and convert the date from yyyymmdd back to mm/dd/yyyy in array2.

Code:
for (my $i=0;$i<=$#array1;$i++) { #Convert date from MM/DD/YYYY to YYYYMMDD
	my @mmddyyyy = split('/',$array1[$i][1]);
	$array1[$i][1] = int($mmddyyyy[2])*10000+int($mmddyyyy[0])*100+int($mmddyyyy[1])*1;
}

my @array2 = sort { $a->[1] <=> $b->[1] } @array1;

for (my $i=0;$i<=$#array2;$i++) { #Convert date from YYYYMMDD to MM/DD/YYYY
	$array2[$i][1] =  substr($array2[$i][1],4,2) . '/' . substr($array2[$i][1],6,2) . '/' . substr($array2[$i][1],0,4);
}

I do a print the first row and second column of array1 and I get back the old date format of mm/dd/yyyy.

Why does column 2 of array1 revert back to the old data ?

It would be easier if your codes include your printing statement. Can’t tell what you are printing and how you are printing and what are your input and output.

In any case, you have a convoluted way of arranging characters

Code:
$date =~ s#(\d\d)/(\d\d)/(\d\d\d\d)#\3\1\2#;
 
Last edited:

peterchan75

Supremacy Member
Joined
Apr 26, 2003
Messages
6,719
Reaction score
529
@davidKTW,

I was stumped by this issue for quite a while. Spent half a day trying to fix it plus a lot of googling. :o Then the "reference" word pop up! @Array2 is referenced to @Array1. So, whatever I have done to @Array2 will affect @Array1. :s22: I have to create a dereference array first.

Code:
my $ref_arr = \@Array1;
my @Array2  = map {[@$_]} @$ref_arr;
@Array2 = sort { $a->[1] <=> $b->[1] } @Array2;

BTW, I tried your regex and got three errors for /3 /1 and /2. Of course, the substr make things look cumbersome. :o
Another google gave me this.
Code:
$date =~ s/([0-9]{4})([0-9]{2})([0-9]{2})/$2\/$3\/$1/g;

Change your regex to this and it works.
Code:
$date =~ s#(\d\d)/(\d\d)/(\d\d\d\d)#$3$1$2#;

Thank you very much for your time.
 
Last edited:

davidktw

Arch-Supremacy Member
Joined
Apr 15, 2010
Messages
13,547
Reaction score
1,301
@davidKTW,

I was stumped by this issue for quite a while. Spent half a day trying to fix it plus a lot of googling. :o Then the "reference" word pop up! @Array2 is referenced to @Array1. So, whatever I have done to @Array2 will affect @Array1. :s22: I have to create a dereference array first.

Code:
my $ref_arr = \@Array1;
my @Array2  = map {[@$_]} @$ref_arr;
@Array2 = sort { $a->[1] <=> $b->[1] } @Array2;

BTW, I tried your regex and got three errors for /3 /1 and /2. Of course, the substr make things look cumbersome. :o
Another google gave me this.
Code:
$date =~ s/([0-9]{4})([0-9]{2})([0-9]{2})/$2\/$3\/$1/g;

Change your regex to this and it works.
Code:
$date =~ s#(\d\d)/(\d\d)/(\d\d\d\d)#$3$1$2#;

Thank you very much for your time.

Yes using "\N" is an older method. "$N" is preferred, but those are just warnings
Code:
$ cat test.pl
#!/usr/bin/env perl

use strict;
use warnings;

my $date = "01/02/1999";

print $date, "\n";
$date =~ s#(\d\d)/(\d\d)/(\d\d\d\d)#\3\1\2#;
print $date, "\n";
$ ./test.pl
\3 better written as $3 at ./test.pl line 9.
\1 better written as $1 at ./test.pl line 9.
\2 better written as $2 at ./test.pl line 9.
01/02/1999
19990102

There is no multi-dimensional arrays in Perl, it's all single dimensional lists referenced from each element of the outer list.

Code:
@nestedlist = ...;
$alist_ref = $nestedlist[I]
@alist = \$alist_ref;
$alist[J];
 

davidktw

Arch-Supremacy Member
Joined
Apr 15, 2010
Messages
13,547
Reaction score
1,301
To demonstrate more regarding references concept in Perl to you
Code:
$ cat multi.pl
#!/usr/bin/env perl

use strict;
use warnings;

my @nested_list = ();
$nested_list[0] = [1,2];
$nested_list[1] = [3,4];

print "Showing you the elements of the nested_list\n";
print "MEMORY ADDRESS:\t", \@nested_list, "\n";
print "CONTENTS:\t", @nested_list, "\n";
print "\n";

foreach my $list (@nested_list) {
  print "Showing you that each element of the nested_list\n";
  print "\t", $list, "\n";
  print "Showing you the contents inside each element (reference to a list)\n";
  print "\t", @$list, "\n";
  print "\n";
}

my @nested_list_2 = (@nested_list);
print "Showing you the elements of the nested_list_2\n";
print "MEMORY ADDRESS:\t", \@nested_list_2, "\n";
print "CONTENTS:\t", @nested_list_2, "\n";
print "\n";

$ ./multi.pl
Showing you the elements of the nested_list
MEMORY ADDRESS:	[COLOR="Blue"]ARRAY(0x7f9c3080c858)[/COLOR]
CONTENTS:	[COLOR="Lime"]ARRAY(0x7f9c300040b0)[/COLOR][COLOR="Magenta"]ARRAY(0x7f9c3080bf70)[/COLOR]

Showing you that each element of the nested_list
	[COLOR="lime"]ARRAY(0x7f9c300040b0)[/COLOR]
Showing you the contents inside each element (reference to a list)
	12

Showing you that each element of the nested_list
	[COLOR="magenta"]ARRAY(0x7f9c3080bf70)[/COLOR]
Showing you the contents inside each element (reference to a list)
	34

Showing you the elements of the nested_list_2
MEMORY ADDRESS:	[COLOR="Purple"]ARRAY(0x7f9c308182d0)[/COLOR]
CONTENTS:	[COLOR="lime"]ARRAY(0x7f9c300040b0)[/COLOR][COLOR="magenta"]ARRAY(0x7f9c3080bf70)[/COLOR]

See how the memory addresses of the objects are different or same. Using map is just a functional form of a loop, it's the same.

All copying are SHALLOW. Notice how I did a shallow copy of nested_list and assigned to nested_list_2 ? The memory address of the list are different, yet the memory addresses of the elements are the same.

You will need to understand memory concepts in Perl, they are very similar to other languages like Java. It is not a bad thing. Most cases of "copy" is more like a reassignment of order or segregation rather than really trying to create a new copy of objects. It is faster and more memory efficient.
 
Last edited:

davidktw

Arch-Supremacy Member
Joined
Apr 15, 2010
Messages
13,547
Reaction score
1,301
Triangle

Code:
$ cat triangle.pl
#!/usr/bin/env perl

use strict;
use warnings;

my @triangle = ();

for (my $i = 0; $i < 10; $i++) {
  $triangle[$i] = [];
  for (my $j = 0; $j < $i; $j++) {
    $triangle[$i][$j] = "$i,$j";
  }
}

foreach my $row (@triangle) {
  foreach my $col (@$row) {
    print "[$col]";
  }
  print "\n";
}
$ ./triangle.pl

[1,0]
[2,0][2,1]
[3,0][3,1][3,2]
[4,0][4,1][4,2][4,3]
[5,0][5,1][5,2][5,3][5,4]
[6,0][6,1][6,2][6,3][6,4][6,5]
[7,0][7,1][7,2][7,3][7,4][7,5][7,6]
[8,0][8,1][8,2][8,3][8,4][8,5][8,6][8,7]
[9,0][9,1][9,2][9,3][9,4][9,5][9,6][9,7][9,8]
 

peterchan75

Supremacy Member
Joined
Apr 26, 2003
Messages
6,719
Reaction score
529
Master davidKTW,
Thank you very much for providing such detailed example.

SalutingEmoji.jpg
 
Important Forum Advisory Note
This forum is moderated by volunteer moderators who will react only to members' feedback on posts. Moderators are not employees or representatives of HWZ Forums. Forum members and moderators are responsible for their own posts. Please refer to our Community Guidelines and Standards and Terms and Conditions for more information.
Top