无法在perl中获取哈希数组

无法在perl中获取哈希数组,perl,perl-data-structures,Perl,Perl Data Structures,我有员工CSV数据,我 尝试将每个员工哈希插入到数组中 open($empOutFh,">empOut.txt") $hash= []; while(<$empFh>) { @columnNames = split /,/, $_ if $.==1; @columnValues = split /,/, $_; %row = map{$_=>shift @columnValues}@columnNames;

我有员工CSV数据,我 尝试将每个员工哈希插入到数组中

open($empOutFh,">empOut.txt")
    $hash= [];
    while(<$empFh>) {
        @columnNames = split /,/, $_ if $.==1;
        @columnValues = split /,/, $_;
        %row = map{$_=>shift @columnValues}@columnNames;
        push @$hash,\%row;
    } 
    print Dumper($hash);

但是,当我尝试打印每一行时,每次都会显示不同的行哈希

问题是,您使用的是单个哈希
%row
,因此
\%row
总是指同一个哈希。每次分配给
%row
,并不是将其设置为新的哈希,而是清除相同的哈希并重新填充它(从而间接影响数组的每个元素)

要解决这个问题,您需要在每个循环迭代中创建一个新的哈希。对代码的最小更改是使用
my
运算符将
%row
声明为具有局部作用域的词法变量:

        my %row = map { $_ => shift @columnValues } @columnNames;
        push @$hash, \%row;
另一种选择是完全消除中间变量,只在每次传递时生成对新匿名哈希的引用:

        push @$hash, { map { $_ => shift @columnValues } @columnNames };

问题是您使用的是单个散列
%row
,因此
\%row
总是引用相同的散列。每次分配给
%row
,并不是将其设置为新的哈希,而是清除相同的哈希并重新填充它(从而间接影响数组的每个元素)

要解决这个问题,您需要在每个循环迭代中创建一个新的哈希。对代码的最小更改是使用
my
运算符将
%row
声明为具有局部作用域的词法变量:

        my %row = map { $_ => shift @columnValues } @columnNames;
        push @$hash, \%row;
另一种选择是完全消除中间变量,只在每次传递时生成对新匿名哈希的引用:

        push @$hash, { map { $_ => shift @columnValues } @columnNames };

如果无法使
映射
正常工作,请改用
foreach
循环。能够维护代码比聪明更重要

#!/usr/bin/env perl

use strict;
use warnings;

# --------------------------------------
use Data::Dumper;

# Make Data::Dumper pretty
$Data::Dumper::Sortkeys = 1;
$Data::Dumper::Indent   = 1;

# Set maximum depth for Data::Dumper, zero means unlimited
local $Data::Dumper::Maxdepth = 0;

# --------------------------------------

# open($empOutFh,">empOut.txt")
my $emp_file = 'empOut.txt';
open my $emp_out_fh, '>', $emp_file or die "could not open $emp_file: $!\n";

#     $hash= [];
my @emps = ();
my @columnNames = ();

#     while(<$empFh>) {
while( my $line = <$empFh> ){
    chomp;

#         @columnNames = split /,/, $_ if $.==1;
    if( $. == 1 ){
        @columnNames = split /,/, $line;
        next;
    }

#         @columnValues = split /,/, $_;
    my @columnValues = split /,/, $line;
    my %row = ();

#         %row = map{$_=>shift @columnValues}@columnNames;
    for my $i ( 0 .. $#columnNames ){
        $row{$columnNames[$i]} = $columnValues[$i];
    }

#         push @$hash,\%row;
    push @emps, \%row;

#     } 
}

#     print Dumper($hash);
print Dumper \@emps;
#/usr/bin/env perl
严格使用;
使用警告;
# --------------------------------------
使用数据::转储程序;
#使Data::Dumper变得漂亮
$Data::Dumper::Sortkeys=1;
$Data::Dumper::Indent=1;
#设置Data::Dumper的最大深度,零表示无限制
本地$Data::Dumper::Maxdepth=0;
# --------------------------------------
#打开($empouth,“>empOut.txt”)
我的$emp_文件='empOut.txt';
打开我的$emp_out_fh,“>”,$emp_文件或“无法打开$emp_文件:$!\n”;
#$hash=[];
我的@emps=();
我的@columnNames=();
#while(){
while(我的$line=){
咀嚼;
#@columnNames=split/,/,$如果$.==1;
如果($。==1){
@columnNames=split/,/,$line;
下一个
}
#@columnValues=split/,/,$;
my@columnValues=split/,/,$line;
我的%row=();
#%row=映射{$\uz=>shift@columnValues}@columnNames;
对于我的$i(0..$#列名){
$row{$columnNames[$i]}=$columnValues[$i];
}
#推送@$hash,\%行;
按@emps,\%行;
#     } 
}
#打印转储程序($hash);
打印转储程序\@emps;

如果无法使
映射正常工作,请使用
foreach
循环。能够维护代码比聪明更重要

#!/usr/bin/env perl

use strict;
use warnings;

# --------------------------------------
use Data::Dumper;

# Make Data::Dumper pretty
$Data::Dumper::Sortkeys = 1;
$Data::Dumper::Indent   = 1;

# Set maximum depth for Data::Dumper, zero means unlimited
local $Data::Dumper::Maxdepth = 0;

# --------------------------------------

# open($empOutFh,">empOut.txt")
my $emp_file = 'empOut.txt';
open my $emp_out_fh, '>', $emp_file or die "could not open $emp_file: $!\n";

#     $hash= [];
my @emps = ();
my @columnNames = ();

#     while(<$empFh>) {
while( my $line = <$empFh> ){
    chomp;

#         @columnNames = split /,/, $_ if $.==1;
    if( $. == 1 ){
        @columnNames = split /,/, $line;
        next;
    }

#         @columnValues = split /,/, $_;
    my @columnValues = split /,/, $line;
    my %row = ();

#         %row = map{$_=>shift @columnValues}@columnNames;
    for my $i ( 0 .. $#columnNames ){
        $row{$columnNames[$i]} = $columnValues[$i];
    }

#         push @$hash,\%row;
    push @emps, \%row;

#     } 
}

#     print Dumper($hash);
print Dumper \@emps;
#/usr/bin/env perl
严格使用;
使用警告;
# --------------------------------------
使用数据::转储程序;
#使Data::Dumper变得漂亮
$Data::Dumper::Sortkeys=1;
$Data::Dumper::Indent=1;
#设置Data::Dumper的最大深度,零表示无限制
本地$Data::Dumper::Maxdepth=0;
# --------------------------------------
#打开($empouth,“>empOut.txt”)
我的$emp_文件='empOut.txt';
打开我的$emp_out_fh,“>”,$emp_文件或“无法打开$emp_文件:$!\n”;
#$hash=[];
我的@emps=();
我的@columnNames=();
#while(){
while(我的$line=){
咀嚼;
#@columnNames=split/,/,$如果$.==1;
如果($。==1){
@columnNames=split/,/,$line;
下一个
}
#@columnValues=split/,/,$;
my@columnValues=split/,/,$line;
我的%row=();
#%row=映射{$\uz=>shift@columnValues}@columnNames;
对于我的$i(0..$#列名){
$row{$columnNames[$i]}=$columnValues[$i];
}
#推送@$hash,\%行;
按@emps,\%行;
#     } 
}
#打印转储程序($hash);
打印转储程序\@emps;