在perl DBI
中,您可以将哈希元素值绑定到查询结果的特定列
这样,
在获取每一行时,哈希元素值将更新为当前行。
我正在试图找出是否有办法在 core perl 中实现这一点, 使用哈希(数组数组)。
最终目标是能够运行这样的事情:
my $i;
my @a = (
[1,2,3],
[4,5,6],
[7,8,9]
);
my %superhash{'first', 'second', 'third'} = (\$i[0], \$i[1], \$i[2]);
for $i (@a) {
print ${$hash{'first'}} . "\n";
}
我希望能够将$hash{'first'}
指向arrayref
中的第一个元素,而无需预先指定数组。
预期产出:
1
4
7
当然,该代码不起作用,因为没有$i
引用的元素,因此它们未定义。
答案 0 :(得分:3)
tie接口是Perl制作魔术变量的方式。在这种情况下,由于for
循环分配给它的循环变量的方式,需要抛出一些glob魔法。
my @a = (
[1,2,3],
[4,5,6],
[7,8,9]
);
{package Tie::Rows;
my %keys = qw(first 0 second 1 third 2);
sub TIEHASH {bless [$_[1]]} # store glob reference
sub FETCH {$${$_[0][0]}[$keys{$_[1]}]} # deref glob as array, lookup key
}
tie my %hash, 'Tie::Rows', *i; # passing the glob here
for our $i (@a) { # since the for loop aliases at that level
print $hash{first} . "\n";
}
打印
1
4
7
您还可以利用动态范围来解决此问题:
sub first () {$$_[0]} # each of these uses the array in $_
sub second () {$$_[1]}
sub third () {$$_[2]}
for (@a) { # for loop puts each array into $_
print second, $/;
}
打印
2
5
8
答案 1 :(得分:0)
你可以用tie
召唤一些东西,即可以像这样做代码:
for my $i (@a) {
tie %hash, 'FirstSecondThird', $i;
print $hash{first}, "\n";
}
魔术是在包FirstSecondThird
的定义中(注意,这不是优化的):
package FirstSecondThird;
sub TIEHASH {
my $class = shift;
my $self = bless { array => shift,
keys => { first => 0, second => 1, third => 2 } }, $class;
$self;
}
sub FETCH {
my ($self, $key) = @_;
my $i = $self->{keys}->{$key};
$self->{array}->[$i];
}
1;
package main;
my @a = ( [1,2,3], [4,5,6], [7,8,9] );
for my $i (@a) {
tie %hash, 'FirstSecondThird', $i;
print $hash{first}+$hash{third}, "\n";
}
收率:
4
10
16
答案 2 :(得分:0)
除非您的数据量巨大,否则最好只将每行复制到哈希中,例如
for my $i (@a) {
my %data;
@data{qw/first second third/} = @$i;
print $data{first}, "\n";
}