2013-07-07 3 views
0

У меня есть сотрудники CSV данных и я попытке вставить каждый сотрудник хэш в массив,не могу получить массив хэшей в Perl

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

Я получаю выход имеет

$VAR1 = [ 
      { 
      'emp_no' => '11000', 
      'hire_date 
' => '1988-08-20 
', 
      'birth_date' => '1960-09-12', 
      'gender' => 'M', 
      'last_name' => 'Bonifati', 
      'first_name' => 'Alain' 
      }, 
      $VAR1->[0], 
      $VAR1->[0], 
      $VAR1->[0] 
     ] 

Но когда я пытаюсь распечатать каждую строку, показывающую разные хеширования строк для каждого времени

ответ

3

Проблема в том, что вы используете один хэш %row, поэтому \%row is всегда ссылаясь на один и тот же хэш. Каждый раз, когда вы назначаете %row, вы не настраиваете его на новый хеш, вы просто очищаете тот же хэш и повторно заселяете его (тем самым затрагивая, косвенно, каждый элемент вашего массива).

Чтобы исправить это, вам нужно создать новый хеш в каждой итерации цикла. Минимальное изменение кода будет объявить %row как лексические переменный с локальной областью, с помощью my оператора:

 my %row = map { $_ => shift @columnValues } @columnNames; 
     push @$hash, \%row; 

Другого варианта заключается в устранении промежуточных переменного целиком, а просто генерировать ссылку на новый анонимный хэш на каждом проходе:

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

Если вы не можете получить map, чтобы работать должным образом, используйте вместо него 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; 
Смежные вопросы