【问题标题】:Perl: pushing elements into array replaces existing value with new variable valuePerl:将元素推入数组用新的变量值替换现有值
【发布时间】:2014-02-27 12:50:20
【问题描述】:

我正在读取一个 csv 文件,需要将一行(第 4 行)中的值作为数据库中的关键元素。但该行包含多个以逗号分隔的值。

  1. 我使用 Text::CSV 解析了文件并将值拆分到第 4 行。

  2. 然后将这些值推入一个数组并插入到一个新文件中,保持其他值不变。

  3. 但在下一次循环运行中,该值被新值替换。

  4. 因此我最终得到了数组中最后一个值的尽可能多的实例(在下面的示例中为 2)

代码:

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 结果是:

#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;

【问题讨论】:

  • 更改了接受的答案,因为@aidan's 提供了一种更好的方法来做同样的事情或更简单。

标签: arrays perl


【解决方案1】:

$row 是一个数组的引用。您反复将此引用推送到@newRows,因此@newRows 最终将持有一组指向同一事物的指针。每次推送到@newRows时,都需要复制数组

例如

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

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

附言你把事情复杂化了:

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

for my $k (split /,\s*/, $row[3])
{
    push @newRows, [@row[0..2], $k, @row[4..$#row]];
}

【讨论】:

  • 这样做的好方法。+1
【解决方案2】:
my $row = \@oneRow;

你的问题。 您持有对@oneRow 的引用 因此,当您访问从 $row 取消引用的第 4 个元素时,您正在更改 @oneRow[3]

的值

您还将该引用推送到列表中

而不是打印 Dumper ,只是 打印@newRows

它将阐明(您将在那里看到相同的指针两次)

【讨论】:

    【解决方案3】:

    我不知道你最后想得到什么。下面的代码将为您提供多维数组

    #!/usr/local/bin/perl
    
    
    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 @newRows;
    my $userString = $oneRow[3];
    my @userNewRow = split(/,/,$userString);
    foreach(@userNewRow) {
        $oneRow[3] =~ s/.*/$_/;
        push @newRows, [@oneRow];
    }
    
    print Dumper \@newRows;
    

    输出:

    $VAR1 = [
              [
                'Vehicle Factory',
                'D3',
                '2518, 1613, 1512, 1109, 912 bus, 712 bus, 613 Export',
                'ajj137035',
                'ddb255570',
                'mdb650204'
              ],
              [
                'Vehicle Factory',
                'D3',
                '2518, 1613, 1512, 1109, 912 bus, 712 bus, 613 Export',
                ' mgp657301',
                'ddb255570',
                'mdb650204'
              ]
            ];
    

    要获取列表,然后将推送更改为:

    push @newRows, @oneRow;
    

    输出:

    $VAR1 = [
              'Vehicle Factory',
              'D3',
              '2518, 1613, 1512, 1109, 912 bus, 712 bus, 613 Export',
              'ajj137035',
              'ddb255570',
              'mdb650204',
              'Vehicle Factory',
              'D3',
              '2518, 1613, 1512, 1109, 912 bus, 712 bus, 613 Export',
              ' mgp657301',
              'ddb255570',
              'mdb650204'
            ];
    

    我不明白创建引用背后的原因,所以我删除了那部分。

    如果您下次也发布您想要的输出,这会有所帮助:)。

    【讨论】:

    • 我添加了参考以复制 Text::CSV 读取 csv 行的方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多