【问题标题】:Adding a hash to an array向数组添加哈希
【发布时间】:2012-01-07 03:07:27
【问题描述】:

我有一个这样的数组,

@switch_ports = ()

然后想将这个哈希的 50 个实例添加到 switch_ports 数组中

%port = (data1 => 0, data2 => 0, changed => 0)

但是,如果我将哈希推送到数组中

push(@switch_ports, %port)

但如果我打印@switch_ports 我才看到

data10data20changed0

所以似乎只是将它们添加到数组中,(加入它们) 如果我尝试循环数组并打印键,它也会失败。

我觉得我的头这么重地撞在桌子上,我快要智障了。

1 - 你可以在数组中存储哈希吗?

2 - 你能有一个哈希数组吗?

试图得到...

switchports
    0
        data1
        data2
        changed
    1
        data1
        ....

因此

foreach $port (@switchport) {
    print $port['data1']
}

将返回数组中所有散列的所有 data1。

是的,我在 Perl 上失败了

【问题讨论】:

    标签: arrays perl multidimensional-array hashtable


    【解决方案1】:

    在 Perl 中,数组和散列成员必须是一个值。在 Perl 5.0 之前,没有(简单的)方法可以做你想做的事。

    但是,在 Perl 5 中,您现在可以使用对哈希的引用。引用只是存储项目的内存位置。要获得引用,请在变量前面加上反斜杠:

    use feature qw(say);
    
    my $foo = "bar";
    say $foo;    #prints "bar"
    say \$foo;   #prints SCALAR(0x7fad01029070) or something like that
    

    因此:

    my @switch_ports = ();
    my %port = ( data1 => 0, data2 => 0, changed => 0 );
    my $port_ref = \%port;
    
    push( @switch_ports, $port_ref );
    

    而且,您不必创建$port_ref

    my @switch_ports = ();
    my %port = ( data1 => 0, data2 => 0, changed => 0 );
    
    push( @switch_ports, \%port );
    

    要获取引用的实际值,只需将符号放回前面:

    #Remember: This is a REFERENCE to the hash and not the hash itself
    $port_ref = $switch_ports[0];
    %port = %{$port_ref};      #Dereferences the reference $port_ref;
    
    print "$port{data1}  $port{data2}  $port{changed}\n";
    

    另一个快捷方式:

    %port = %{$port[0]};   #Dereference in a single step
    print "$port{data1}  $port{data2}  $port{changed}\n";
    

    或者,甚至更短,在你进行时取消引用:

    print ${$port[0]}{data1} . " " . ${$port[0]}{data2} . " " . ${$port[0]}{changed} . "\n";
    

    还有一点句法甜味剂。意思相同,但更容易阅读:

    print $port[0]->{data1} . " " . $port[0]->{data2} . " " . $port[0]->{changed} . "\n";
    

    看看 Perldoc 的 perlreftutperlref。第一个是教程。

    【讨论】:

    • Perl 5.000 于 1994 年 10 月 17 日发布。我认为到 17 年后的 2011 年,关于 Perl4 行为的免责声明不再是非常必要的 :)
    • 你会认为是这样。然而,有很多 Perl 教程仍然停留在古老的 Perl 3.x 语法中:如果它对爷爷来说足够好,那对我来说就足够好了!。我仍然看到人们使用require "find.pl"; 而不是use File::Find;chop 而不是chomp。甚至许多现代的Learn Perl书籍也从未被引用。
    【解决方案2】:

    当你尝试时:

    %port = (data1 => 0, data2 => 0, changed => 0);
    push @switch_ports, %port;
    

    真正发生的是:

    push @switch_ports, "data1", 0, "data2", 0, "changed", 0;
    

    因为在列表上下文中使用时,数组和散列将automatically break into their elements

    当您想创建 50 个哈希实例时,最好不要像其他人建议的那样使用对现有哈希的引用,因为这只会创建对 相同的 50 个不同引用> 哈希。由于显而易见的原因,它会崩溃和燃烧。

    你需要的是这样的:

    push @array, { data1 => 0, data2 => 0, changed => 0 } for 1 .. 50;
    

    这将向数组添加 50 个唯一的匿名哈希。大括号表示匿名哈希的构造,并返回对其的标量引用。

    ETA:您关于如何访问此数据的示例是错误的。

    foreach $port (@switchport) {
        print $port['data1'];    # will use @port, not $port
    }
    

    在标量变量上使用下标将尝试访问该命名空间中的数组,而不是标量。在 perl 中,有两个单独的变量 $port@port 是有效的。括号用于数组,而不是哈希。使用引用时,还需要使用箭头运算符:$port->{data1}。因此:

    for my $port (@switchport) {
        print $port->{data1};
    }
    

    【讨论】:

      【解决方案3】:

      您可以在数组中存储 哈希的引用:

      push @switchport, \%port; # stores a reference to your existing hash
      

      push @switchport, { %port }; # clones the hash so it can be updated separately
      

      然后迭代,比如说,

      foreach my $port (@switchport) {
          print $port->{'data1'}; # or $$port{'data1'}
      }
      

      man perlref

      【讨论】:

        【解决方案4】:

        为那些使用此问题的人简化寻找一般方法 - 如标题问题。 mysql主题:

        my @my_hashes = ();
        my @$rows = ... # Initialize. Mysql SELECT query results, for example.
        
        if( @$rows ) {
            foreach $row ( @$rows ) { # Every row to hash, every hash to an array.
                push @my_hashes, { 
                    id => $row->{ id }, 
                    name => $row->{ name }, 
                    value => $row->{ value }, 
                };
            }
        }
        

        循环打印:

        for my $i ( 0 .. $#my_hashes ) {
            print "$my_hashes[$i]{ id }\n ";
            print "$my_hashes[$i]{ name }\n ";
            print "$my_hashes[$i]{ value }\n ";
        }
        

        for my $i ( 0 .. $#my_hashes ) {
        for my $type ( keys %{ $my_hashes[$i] } ) {
             print "$type=$my_hashes[$i]{$type} ";
        }
        

        }

        【讨论】:

          猜你喜欢
          • 2021-05-06
          • 1970-01-01
          • 1970-01-01
          • 2012-09-03
          • 2015-04-30
          • 2017-11-15
          • 1970-01-01
          • 2015-04-01
          • 2018-02-17
          相关资源
          最近更新 更多