Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl: pushing elements into array replaces existing value with new variable value

Tags:

arrays

perl

I am reading a csv file and need to make values in a row(4th row) as the key elements in database. But the row contains multiple values comma separated.

  1. I parsed the file with Text::CSV and split the values in 4th row.

  2. Then push these values in an array and insert into a new file keeping other values same.

  3. But in next run of loop and the value is replaced by the new value.

  4. Hence I end up with as many instance of the last value in the array (2 in example below)

The code :

use Data::Dumper;
use strict;
my @oneRow = ('Vehicle Factory',
          'D3',
          '2518, 1613, 1512, 1109, 912 bus, 712 bus, 613 Export',
          'ajj137035, mgp657301',
          'ddb255570',
          'mdb650204'
          );
my $row = \@oneRow;
my @newRows;
my $userString = $row->[3];
        my @userNewRow = split(/,/,$userString);
        foreach(@userNewRow) {
            $row->[3] =~ s/.*/$_/;
            print Dumper $row;
            push @newRows, $row;
            print Dumper @newRows;
        }

Dumper Results are:

#comment: this is Dumper $row result of first run in loop
$VAR1 = [
          'Vehicle Factory',
          'D3',
          '2518, 1613, 1512, 1109, 912 bus, 712 bus, 613 Export',
          'ajj137035',
          'ddb255570',
          'mdb650204'
        ];
 #comment: this is the Dumper @newRows result of first run in loop
$VAR1 = [
          'Vehicle Factory',
          'D3',
          '2518, 1613, 1512, 1109, 912 bus, 712 bus, 613 Export',
          'ajj137035',
          'ddb255570',
          'mdb650204'
        ];
#comment: this is the Dumper $row result of 2nd run in loop 
$VAR1 = [
          'Vehicle Factory',
          'D3',
          '2518, 1613, 1512, 1109, 912 bus, 712 bus, 613 Export',
          ' mgp657301',
          'ddb255570',
          'mdb650204'
        ];
#comment: this is Dumper @newRows result of second run in loop 
the new value is inserted but the first value becomes same as new value
$VAR1 = [
          'Vehicle Factory',
          'D3',
          '2518, 1613, 1512, 1109, 912 bus, 712 bus, 613 Export',
          ' mgp657301',
          'ddb255570',
          'mdb650204'
        ];
$VAR2 = $VAR1;
like image 869
norbdum Avatar asked Mar 20 '23 10:03

norbdum


2 Answers

$row is a reference to an array. You're repeatedly pushing this reference onto @newRows so @newRows will ultimately hold a set of pointers to the same thing. You need to make a copy of the array each time you push onto @newRows

e.g.

my @arr = (1, 2, 3);
my $ref_a = \@arr;
my $ref_b = \@arr;

$ref_a->[0] = "test";
print $ref_b->[0]; # prints "test";

p.s. you're over-complicating things:

my @row = ('Vehicle Factory', 'D3', '2518, ...', ...);
my @newRows = ();

for my $k (split /,\s*/, $row[3])
{
    push @newRows, [@row[0..2], $k, @row[4..$#row]];
}
like image 142
aidan Avatar answered Apr 26 '23 11:04

aidan


my $row = \@oneRow;

there's your problem. you are holding a reference to @oneRow so that when you access the 4th element de-referenced from $row you are changing the value of @oneRow[3]

you've also pushed that reference into the list

instead of printing Dumper , just print @newRows

it will be elucidating (you will see the same pointer in there twice)

like image 26
vish Avatar answered Apr 26 '23 13:04

vish