2013-06-25 38 views
0

我在使用Perl將以下csv代碼片段轉換爲哈希值時遇到了問題。將csv轉換爲陣列的perl哈希值

emp_no,birth_date,first_name,last_name,gender,hire_date 
10001,1953-09-02,Georgi,Facello,M,1986-06-26 
10002,1964-06-02,Bezalel,Simmel,F,1985-11-21 
10003,1959-12-03,Parto,Bamford,M,1986-08-28 
10004,1954-05-01,Chirstian,Koblick,M,1986-12-01 
10005,1955-01-21,Kyoichi,Maliniak,M,1989-09-12 

哈希應該是這樣的:

$employee = { 
emp_no=>[10001,10002,10003,10004,10005], 
birth_date=>[1953-09-02,1964-06-02,1959-12-03], 
simarly for fistname , lastname and hire_date 

} 

我已經試過這樣

while(<FH>){ 


    @keys = split /,/,$_ if $.==1; #for the first line 

     @row = split /,/,$_; 

      push @hash{@keys},@row; 

} 
+1

什麼是你的問題?如果您無法使腳本正常工作,請顯示您嘗試過的內容。 – Barmar

+5

將它轉換爲散列數組而不是散列數組不是更好嗎? – Barmar

+0

請參閱http://search.cpan.org/~makamaka/Text-CSV-1.32/lib/Text/CSV.pm瞭解處理CSV文件的包。 – Barmar

回答

1

喜歡的東西:

while (my $line = readline($fh)) { 
    chomp $line; 
    my ($emp_no, $birth_date, $first_name, $last_name, $gender, $hire_date) = split /,/, $line; 
    push @{ $employee->{emp_no} }, $emp_no; 
    #etc. 
} 
2

只能使用這個,如果你因爲某些原因不能使用 http://metacpan.org/pod/Text::CSV模塊:)

my %employee; 
while (<ARGV>)) { 
    next if /^emp/; 
    my @r = split/,/; 
    push @{$employee{$_}}, shift @r 
     for qw(emp_no birth_date first_name last_name gender hire_date); 
} 
+0

+1指出**有一個模塊來做到這一點** – lexu

0

Text :: CSV會將您的數據存儲爲哈希數組,每個哈希鍵都是列名。這似乎是最有意義的。例如:

my %employee = %{ $employee_array[2] }; #Row #3 of your file: 
print "The name of the third employee is $employee{first_name} $employee{last_name}\n"; 

因此,數組的單個行包含該員工的所有數據。

在你的情況,你必須保證指數相同的多個陣列:

print "The name of the third employee is $first_name[2] $last_name[2]\n"; 

如果你有這樣的員工操作對象的功能,你必須通過所有的數組該函數:

print_paycheck($first_name[1], $last_name[1], $employee_num[1], $hire_date[1]...); 

而如果你有散列的數組,你可以這樣做:

print_paycheck($employee_array[1]); 

我認爲你不瞭解參考資料。許多初學Perl的書不討論它們,它們不是Perl的明顯延伸。但是,引用允許您創建這些更復雜的數據結構。幸運的是,Perldoc擁有出色的Tutorial。我建議你閱讀它。

實際上,您可能希望存儲由員工編號鍵入的數據,因此您需要哈希散列。

下面是散列哈希的一個例子。 注意:這是而不是我會做這個程序的方式。首先,如果可用,我會使用Text::CSV,然後我實際上會使用面向對象的方法。不過,我想保持這是一個簡單的哈希散列

use warnings; 
use strict; 
use feature qw(say); 

use Data::Dumper; 

my %employee_hash; 
<DATA>; #Field Names 
while (my $employee_data = <DATA>) { 
    chomp $employee_data; 
    my ($employee, $birth_date, $first_name, $last_name, $gender, $hire_date) = split /,/, $employee_data; 
    $employee_hash{$employee}->{birth_date} = $birth_date; 
    $employee_hash{$employee}->{first_name} = $first_name; 
    $employee_hash{$employee}->{last_name} = $last_name; 
    $employee_hash{$employee}->{gender}  = $gender; 
    $employee_hash{$employee}->{hire_date} = $hire_date; 
} 

for my $employee (sort keys %employee_hash) { 
    my $gender; 
    if ($employee_hash{$employee}->{gender} eq "M") { 
     $gender = "he"; 
    } 
    else { 
     $gender = "she"; 
    } 

    printf qq(Employee: %s is %s %s and %s was hired on %s\n), 
     $employee, 
     $employee_hash{$employee}->{first_name}, 
     $employee_hash{$employee}->{last_name}, 
     $gender, 
     $employee_hash{$employee}->{hire_date}; 
} 

__DATA__ 
emp_no,birth_date,first_name,last_name,gender,hire_date 
10001,1953-09-02,Georgi,Facello,M,1986-06-26 
10002,1964-06-02,Bezalel,Simmel,F,1985-11-21 
10003,1959-12-03,Parto,Bamford,M,1986-08-28 
10004,1954-05-01,Chirstian,Koblick,M,1986-12-01 
10005,1955-01-21,Kyoichi,Maliniak,M,1989-09-12