将哈希值绑定到迭代的数组数组的元素

时间:2011-11-08 04:26:23

标签: arrays perl reference

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引用的元素,因此它们未定义。

3 个答案:

答案 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";
}