Perl:从数组创建哈希表

4
如果我有以下数组:
my @header_line = ('id', 'name', 'age');

我该如何创建一个哈希值,使其等同于下面的行?
my %fields = { id => 0, name => 1, age => 2};

我想这么做的原因是可以使用有意义的名称而不是用于索引的数字。例如:

$row->[$fields{age}]; # rather than $row->[2] 

为什么不将 $row 改为 %row(哈希)呢? - knittl
1
它来自Text::CSV,例如:my $row = $csv->getline($fh) - FunLovinCoder
2
由于您有@header_line,因此可以很容易地将$row转换为哈希:my %row_hash = map { $_ => shift @{$row} } @header_line;。只是另一种选择,但使用$row_hash{age}可能更清晰,而不必使用$row->[$fields{age}]符号表示法... - plusplus
由于您有@header_line,因此可以很容易地将$row转换为哈希表:my %row_hash; @row_hash{@header_line} = @{$row};。我不得不花一点时间思考您的代码如何工作,哈希切片更加简洁。 - Oesor
5个回答

15
my %fields;
@fields{@header_line} = (0 .. $#header_line);

@swisstony:我突然想到,如果你的索引是静态已知的,那么使用常量会更方便。 use constant { id => 0, name => 1, age => 2}; print $row->[age]; - Roman Cheplyaka
我明白了,但那么我就需要维护两个数据结构。我已经有一个叫做header_line的数组,在打印列名时使用($csv->print( $fh, get_header_line();). 我还必须维护一个单独的哈希表用于索引。我应该说,实际上我的header_line中有大约40个列名,而不是我的示例中的3个。如果我能将header_line创建为哈希表的数组引用,这就是Text::CSV想要的,但我不确定如何做到这一点。 - FunLovinCoder

6
my %fields = map { $header_line[$_] => $_ } 0..$#header_line;

3

你在回复评论中说这是来自 Text::CSV。这个模块有一种方法可以将其导入哈希。

$csv->column_names( @header_line );
$row = $csv->getline_hr( $FH );
print $row->{ 'id' };


不知道column_names和getline_hr - 它们是在2008年添加的,所以相对较新(就Text :: CSV而言)。这使得代码更加整洁... - plusplus
我差不多把这个程序跑通了。问题在于$csv_o->print( $fh_o, $row );失败了,因为它需要一个数组引用。我该如何使用csv_o对象输出哈希引用呢?顺便说一下,我的脚本读入一个CSV文件,添加一些字段,更改所有列名(@header_line是新的列名),然后写出一个新的CSV文件。我没有意识到我需要的东西可能就在我的眼前。非常感谢您的评论! - FunLovinCoder
我将此作为一个新问题提出,因为它与这个问题非常不同:http://stackoverflow.com/questions/4163048/perl-with-textcsv-can-i-write-out-a-hash-ref - FunLovinCoder

1
my %fields = ();
for (my $i = 0; $i < scalar(@header_line); $i++) {
   $fields{$header_line[$i]} = $i;
}

0

TIMTOWTDI

my %fields = ();
foreach my $field(@header_line)
{
  $fields{$field} = scalar(keys(%fields));
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接