如何在Perl中从数组中散列?

如何在Perl中从数组中散列?

How to get hashes out of arrays in Perl?

我想在perl中写一个小小的" DBQuery"函数,这样我就可以使用一个内联函数来发送一条SQL语句并接收回来,以及一个散列数组,即一个记录集。但是,我遇到了Perl语法问题(可能还有一些奇怪的指针/引用问题),这阻止了我从数据库中获取的哈希值中打包信息。下面的示例代码演示了此问题。

我可以使用以下语法从数组内的哈希中获取数据" Jim":

1
print $records[$index]{'firstName'}

返回"吉姆"

但是如果我首先将数组中的哈希记录复制到它自己的哈希变量中,那么我很奇怪地无法再访问该哈希中的数据:

1
2
    %row = $records[$index];
    $row{'firstName'};

返回"(空白)

这里是显示问题的完整示例代码。任何帮助表示赞赏:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
my @records = (
   {'id' => 1, 'firstName' => 'Jim'},
   {'id' => 2, 'firstName' => 'Joe'}
);
my @records2 = ();

$numberOfRecords = scalar(@records);
print"number of records:" . $numberOfRecords ."\
"
;
for(my $index=0; $index < $numberOfRecords; $index++) {

   #works
   print 'you can print the records like this: ' . $records[$index]{'firstName'} ."\
"
;

   #does NOT work
   %row = $records[$index];
   print 'but not like this: ' . $row{'firstName'} ."\
"
;

}

嵌套的数据结构包含哈希引用,而不是哈希。

1
2
3
4
5
6
7
8
9
# Will work (the -> dereferences the reference)
$row = $records[$index];
print"This will work:", $row->{firstName},"\
"
;

# This will also work, by promoting the hash reference into a hash
%row = %{ $records[$index] };
print"This will work:", $row{firstName},"\
"
;

如果您曾经遇到过深刻的Perl数据结构,则可以通过使用Data :: Dumper进行打印以将其打印为人类可读(和Per??l可分析的)形式而受益。


哈希数组实际上并不包含哈希,而是对哈希的引用。
这行:

1
%row = $records[$index];

为%row分配一个条目。关键是标量:

1
   {'id' => 1, 'firstName' => 'Jim'},

哪个是对哈希的引用,但该值为空白。

您真正想做的是:

1
2
$row = $records[$index];
$row->{'firstName'};

否则:

1
2
$row = %{$records[$index];}
$row{'firstName'};

其他人则对哈希与哈希引用进行了评论。我觉得还应该提到的另一件事是您的DBQuery函数-似乎您正在尝试执行DBI中已内置的某些操作?如果我正确理解了您的问题,则您正在尝试复制类似selectall_arrayref:

的内容

This utility method combines"prepare","execute" and"fetchall_arrayref" into a single call. It returns a reference to an array containing a reference to an array (or hash, see below) for each row of data fetched.


要添加到上面的可爱答案中,请允许我补充说,您应该始终,始终,始终(是,三个"总是"是)在代码顶部使用"使用警告"。如果这样做,您将得到警告"参考在-e第1行找到了偶数大小的列表的位置"。


数组中实际具有的是hashref,而不是哈希。如果您不理解此概念,则可能值得阅读perlref文档。

要获取您需要做的哈希

1
my %hash = %{@records[$index]};

例如

1
2
3
4
5
6
7
8
9
my @records = (
     {'id' => 1, 'firstName' => 'Jim'},
     {'id' => 2, 'firstName' => 'Joe'}
  );

  my %hash = %{$records[1]};

  print $hash{id}."\
"
;

尽管。我不确定您为什么要这么做,除非出于学术目的。否则,我建议在DBI模块中使用fetchall_hashref / fetchall_arrayref,或使用类似Class :: DBI的方法。


还要注意要使用的一个很好的perl习惯用法是

1
2
3
4
for my $rowHR ( @records ) {
   my %row = %$rowHR;
   #or whatever...
}

遍历列表。


推荐阅读