【问题标题】:Modify array of hashes by reference通过引用修改哈希数组
【发布时间】:2016-04-02 07:22:02
【问题描述】:

我想通过子函数修改一个哈希数组,因此我想通过引用传递数组,在子函数中取消引用并进一步修改它。

在此修改后,数组应立即保存修改后的值,我不想显式返回修改后的哈希(想在原始数组上工作)。

不幸的是,我没有成功。有很多关于访问哈希数组引用的网络提示,但我找不到操纵数组的提示。

my @array_of_hashes = ( {name => "Alice"}, 
                        {name => "Bob"} );
my $myhashref = \%{$array_of_hashes[0]};  # This holds a ref to {name=>"Alice"}
my %myhash = %{$myhashref};   # De-reference, shall be the Hash to work on
print $myhash{name} . "\n";   # This shows Alice
$myhash{age}=32;     # Want to add 'age' to the Alice Hash, does not work

这个修改后的哈希不显示{age}。当您查看@array_of_hashesprint Data::Dump::dump(@array_of_hashes) 时,$myhash{age}=32; 行对@array_of_hashes 没有影响。

我怎样才能交出参考,例如@array_of_hashes 的第一个元素到函数以及如何在函数中取消引用它才能修改 @array_of_hashes 中的哈希?

【问题讨论】:

  • my %myhash = %{$myhashref}; # De-reference, shall be the Hash to work on 这将使用 myhashref 的内容创建一个名为 myhash 的新变量。它是它的副本,它不是同一个变量,因此您对 myhash 所做的任何更改都不会反映在 myhashref 中
  • $myhashref->{age} = 32 有效。虽然您可以这样做:my $hashref = $array_of_hashes[0],但您不需要引用它的取消引用。
  • 好的,谢谢大家赐教!取消引用总是会创建原始对象的副本。每次当函数要修改作为函数参数给出的变量时,都必须考虑这一点!

标签: arrays perl hash reference


【解决方案1】:

你说:我想通过一个子函数来修改一个哈希数组

如果我理解正确,可以使用以下方法:

use 5.014;
use warnings;
use Data::Dumper;

my @aoh = (
    {name => "Alice"}, 
    {name => "Bob"}
);
do_some(\@aoh); #pass arrayref
$aoh[1]->{text} = 'huhu';
say Dumper \@aoh;
say "$aoh[1]->{name} has age $aoh[1]->{age} and says $aoh[1]->{text}";

sub do_some {
    my $ar = shift;
    for my $hr (@$ar) { #for each array element
        $hr->{age} = int rand 100;
    }
}

# however (IMHO)
# using arrayref from the beginning is more cleaner
my $aohr = [
    {name => "Alice"}, 
    {name => "Bob"}
];
do_some($aohr);
$aohr->[0]->{text} = 'juju';
say Dumper $aohr;
say "$aohr->[0]->{name} has age $aohr->[0]->{age} and says $aohr->[0]->{text}";
#could use the shortened form
#say "$aohr->[0]{name} has age $aohr->[0]{age} and says $aohr->[0]{text}";

上面产生例如:

$VAR1 = [
          {
            'age' => 31,
            'name' => 'Alice'
          },
          {
            'age' => 10,
            'text' => 'huhu',
            'name' => 'Bob'
          }
        ];

Bob has age 10 and says huhu
$VAR1 = [
          {
            'name' => 'Alice',
            'age' => 94,
            'text' => 'juju'
          },
          {
            'name' => 'Bob',
            'age' => 57
          }
        ];

Alice has age 94 and says juju

【讨论】:

    【解决方案2】:

    在创建数组时,您已经为每个哈希创建了一个引用。然后你defrencing散列并将其分配给一个新的散列变量。

    my %myhash = %{$myhashref};   # De-reference, shall be the Hash to work on
    

    所以你现在有了一个新的哈希,它是作为 alice 哈希的副本创建的。但是,新哈希和 alice 哈希是分开的。然后,您可以修改新的哈希值,但它不会反映在 alice 哈希值中,因为它们是分开的。相反,您应该修改现有的哈希引用。比如下面试试。

    use strict;
    use warnings;
    use Data::Dumper;
    
    my @array_of_hashes = ( {name => "Alice"}, 
                            {name => "Bob"} );
    print $array_of_hashes[0]->{'name'}, "\n";#this shows alice
    $array_of_hashes[0]->{'age'}=32;     # Want to add 'age' to the Alice Hash, does not work
    
    
    print Dumper \@array_of_hashes;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-04
      • 2021-10-14
      • 2011-04-16
      • 1970-01-01
      • 1970-01-01
      • 2016-05-29
      • 2015-12-23
      相关资源
      最近更新 更多