2011-01-21 36 views
0

我需要帮助了解如何适应$ hash {$ i}使用不同大小的@headers数组加载的情况。 使用严格; 使用警告;如何从变量大小的数组初始化HoH

my $file = "list.csv"; 

    open (FILE,"$file") || die "Can't open file: $!\n"; 
    my (@lines) = <FILE>; 
    close(FILE); 

    my @headers = split(',',$lines[0]);#split up header line 

    my %hash; 
    for (my $i=1; $i < scalar(@lines); $i++) 
    { 
     my @strings = split(',',$lines[$i]; 

# NEED help here 
     $hash{$i} = { 
      $headers[0] => $strings[0], 
      $headers[1] => $strings[0], 
      $headers[2] => $strings[0], 
      $headers[3] => $strings[0], 
      $headers[4] => $strings[0], 
      $headers[5] => $strings[0] 
      }; 

    } 

是否有一种方法来加载散列索引为标量(@headers)= 5,6,7 ...等情况下?是否有程序上的等价物像...

$hash{$i} = { 
     $headers[0] => $strings[0], 
       ... 
     $headers[n] => $strings[n] 
     }; 

$hash{$i} = {@headers => @strings); 
+0

另请参阅:http://stackoverflow.com/questions/38345/is-there-an-elegant-zip-to-interleave-two-lists-in-perl -5和http://stackoverflow.com/questions/3715957/how-can-i-assign-two-arrays-to-a-hash-in-perl/3715993#3715993 – 2011-01-21 00:45:15

回答

5

你想要的成语是:

@{ $hash{$i} }{ @headers } = @strings; 

这被称为slicing

鉴于您正在阅读CSV数据,您可能会看到某些CPAN模块,例如Text::CSV

+0

+1 - 总是使用CPAN - 你不需要正确**解析CSV文件的头痛。永远。 – DVK 2011-01-21 11:27:51

1

TIMTOWTDI

#!/usr/bin/perl 

use strict; 
use warnings; 

my $file = "list.csv"; 

# Use lexical filehandles, not globals; use 3-arg open; don't quote filename 
open (my $fh, '<', $file) or die "Can't open file: $!\n"; 
my(@lines) = <$fh>; 
close($fh); 

# split takes a regex; also, notice the shift 
my @headers = split(/,/, shift @lines); 

my %hash; 

# Use perly for loops here 
foreach my $i (0..$#lines) 
# This works, too 
#for my $i (0..$#lines) 
{ 
    # split takes a regex 
    my @strings = split(/,/, $lines[$i]); 

    # One way (probably best) 
    @{ $hash{$i} }{ @headers } = @strings; 
    # Another way 
    #$hash{$i} = { map { $headers[$_] => $strings[$_] } (0 .. $#strings) }; 
    # Another way 
    #$hash{$i}{ $headers[$_] } = $strings[$_] = for(0..$#strings); 

} 

#use Data::Dumper; 
#print Dumper \%hash; 

但是,是的,使用Text::CSV(或更快Text::CSV_XS)会比试图手动拆分CSV自己(如果有空间发生了什么?发生了什么,甚至更好,如果字段和/或标题被引用?这是一个解决的问题。)