Perl:数组和哈希 [英] Perl: array and hash

查看:81
本文介绍了Perl:数组和哈希的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

进一步找到我之前的问题的答案 Perl:切片哈希数组 ,我再次陷入困境,无法看到我做错了什么。

Further to finding an answer to my earlier question Perl: slicing an array of hashes, I am stuck again and unable to see what I have done wrong.

我拥有的是

Array(Array0(Hash0,Hash1),Array1(Hash0,Hash1), Array2(Hash0,Hash1)...)

Array( Array0(Hash0,Hash1),Array1(Hash0,Hash1),Array2(Hash0,Hash1)...)

use strict;
use warnings;

my @DDs = ();
my @Ds  = ();
my %hsh = ();

my %dot1 = ( 'x' => 1,   'y' => 2,   'r' => 3 );
my %dot2 = ( 'x' => 4,   'y' => 5,   'r' => 6 );
my %dot3 = ( 'x' => 7,   'y' => 8,   'r' => 9 );
my %dot4 = ( 'x' => 1.1, 'y' => 1.2, 'r' => 1.3 );
my %dot5 = ( 'x' => 2.1, 'y' => 2.2, 'r' => 2.3 );
my %dot6 = ( 'x' => 3.1, 'y' => 3.2, 'r' => 3.3 );
my %dot7 = ( 'x' => 4.1, 'y' => 4.2, 'r' => 4.3 );
my %dot8 = ( 'x' => 5.1, 'y' => 5.2, 'r' => 5.3 );

my @dotsA = ( \%dot1, \%dot2 );
my @dotsB = ( \%dot3, \%dot4 );
my @dotsC = ( \%dot5, \%dot6 );
my @dotsD = ( \%dot7, \%dot8 );

my %Ds = ( \@dotsA, \@dotsB, \@dotsC, \@dotsD );

@DDs = $Ds[1];    #expect @dotsB with scalar of 2

###"Can't use an undefined value as HASH reference" error here
%hsh = %{ $DDs[0] };    #expect %dot3

print scalar @DDs, "\n";    #expect 2 but has value of 1
print $hsh{'x'}, "\n";


推荐答案


参考在/Users/schwern/tmp/test.plx第10行找到了期望的大小均匀的列表。

第10行是这样的:

my %dot1 = {'x'=>1,'y'=>2,'r'=>3};

这是Perl神秘的说法,您将哈希引用输入了哈希。不幸的是,Perl区分事物和对该事物的引用。

This is Perl's cryptic way of saying you fed a hash reference to a hash. Perl, unfortunately, distinguishes very strongly between things and references to that thing.

%dot1 是一个哈希。它获取一个列表并将其转换为哈希。像(x => 1,y => 2,r => 3)之类的列表。 {x => 1,y => 2,r => 3} 创建一个哈希引用。这是一件事,一个标量。这就像说 my%dot1 =(42)

%dot1 is a hash. It takes a list and turns it into a hash. A list like ( x => 1, y => 2, r => 3). { x => 1, y => 2, r => 3 } creates a hash reference. That's a single thing, a scalar. It's like saying my %dot1 = (42). It doesn't make any sense.


  • %dot1是一个散列,它想要一个像(x = > 1,y => 2)

  • $ dot1是标量,它可以存储像 {x = > 1,y => 2}

  • %dot1 is a hash, it wants a list like (x => 1, y => 2)
  • $dot1 is a scalar, it can store a hash reference like { x => 1, y => 2 }.
my %Ds = (\@dotsA,\@dotsB,\@dotsC,\@dotsD);

哈希需要一个键和一个值对。 last_name => Schwern 。当给它一堆这样的数组引用时,它将读取它们为key1,value1,key2,value2 ...,但是它用作键是什么呢?它使用该引用的字符串化,例如 ARRAY(0x7fb721800468)

A hash requires a key and a value, pairs. last_name => "Schwern". When you give it a bunch of array references like that, it will read them as key1, value1, key2, value2... but what is it using as the key? It's using the stringification of that reference, something like ARRAY(0x7fb721800468).

如果您要求 $ D {\ @ dotsA} ,您将获得对 @dotsB 的引用。您将无法获得 @dotsA ,Perl哈希键只是一个字符串,而不是引用。

If you asked for $D{\@dotsA} you'll get back a reference to @dotsB. You will not be able to get @dotsA back, a Perl hash key is just a string, not a reference.

这不是在哈希表中存储数组的好方法。我不确定您要完成什么,但是您可能想按名称引用它们。

This isn't a very good way to store an array in a hash. I'm not sure what you're trying to accomplish, but you probably want to reference them by name.

# A hash of lists.
my %Ds = ( A => \@dotsA, B => \@dotsB, C => \@dotsC, D => \@dotsD );

# Get back a reference to @dotsA.
my $dotsA = $Ds{A};

但是看下面的代码, @DDs = $ Ds [1] ; ,我想您是要初始化 @Ds 而不是%Ds

But looking at the following code, @DDs = $Ds[1];, I think you meant to initialize @Ds instead of %Ds.

@Ds = (\@dotsA,\@dotsB,\@dotsC,\@dotsD);

现在,以下工作...有点类似。

And now the following works... sort of. More later.

@DDs = $Ds[1]; #expect @dotsB with scalar of 2

与PHP不同,哈希和数组是完全不同的东西。 我的@Ds 我的%Ds 声明了完全不同的变量。您同时使用 $ Ds 访问它们都无济于事。在Perl5中,该标记表示将要退货的内容。 $ Ds [1] $ Ds {foo} 都使用 $ Ds ,因为它们正在返回标量。 @Ds [1,2] @Ds {(foo,bar)} 使用 @Ds ,因为它们正在返回列表(称为切片)。

Unlike in PHP, hashes and arrays are totally different things. my @Ds and my %Ds declare totally different variables. It doesn't help that you access them both with $Ds. In Perl5, the sigil indicates what's going to get returned. $Ds[1] and $Ds{foo} both use $Ds because they're returning a scalar. @Ds[1,2] and @Ds{(foo, bar)} use @Ds because they're returning a list (known as a slice). Confusing, but that's how it works.

@DDs = $Ds[1]; #expect @dotsB with scalar of 2

您没有得到 @dotsB ,您将获得对 @dotsB 的引用。 Perl中的所有复杂数据结构都存储引用,而不是实际值。就像 $ DDs [0] = \ @ dotsB

You're not getting @dotsB, you're getting a reference to @dotsB. All complex data structures in Perl store references, not the actual value. This is like $DDs[0] = \@dotsB. If you want to get the actual value you have to dereference it.

@DDs = @{$Ds[1]};  # Now @DDs has a copy of @dotsB







And finally it works.

#!/usr/bin/perl
use strict;
use warnings;
use v5.10;    # for say()

my %dot1 = ('x'=>1,'y'=>2,'r'=>3);
my %dot2 = ('x'=>4,'y'=>5,'r'=>6);
my %dot3 = ('x'=>7,'y'=>8,'r'=>9);
my %dot4 = ('x'=>1.1,'y'=>1.2,'r'=>1.3);
my %dot5 = ('x'=>2.1,'y'=>2.2,'r'=>2.3);
my %dot6 = ('x'=>3.1,'y'=>3.2,'r'=>3.3);
my %dot7 = ('x'=>4.1,'y'=>4.2,'r'=>4.3);
my %dot8 = ('x'=>5.1,'y'=>5.2,'r'=>5.3);

my @dotsA = (\%dot1,\%dot2);
my @dotsB = (\%dot3,\%dot4);
my @dotsC = (\%dot5,\%dot6);
my @dotsD = (\%dot7,\%dot8);

my @Ds = (\@dotsA,\@dotsB,\@dotsC,\@dotsD);
my @DDs = @{$Ds[1]}; #expect @dotsB

my %hsh = %{$DDs[0]}; #expect %dot3

say scalar @DDs; #expect 2
say $hsh{'x'};






我也建议您可以直接工作使用引用,因为这就是复杂的数据结构:引用。从引用到值的来回转换令人困惑。与引用一起工作是在代码中,在您的头脑中进行转换以及在程序中完成的复制工作较少的事情。


I would also advise that you get comfortable working directly with references since that's what complex data structures are: references. Converting back and forth from references to values is confusing. Working with references is one less thing to convert in your code, in your head, and less copying done in your program.

#!/usr/bin/perl
use strict;
use warnings;
use v5.10;    # for say()

my $dot1 = {'x'=>1,'y'=>2,'r'=>3};
my $dot2 = {'x'=>4,'y'=>5,'r'=>6};
my $dot3 = {'x'=>7,'y'=>8,'r'=>9};
my $dot4 = {'x'=>1.1,'y'=>1.2,'r'=>1.3};
my $dot5 = {'x'=>2.1,'y'=>2.2,'r'=>2.3};
my $dot6 = {'x'=>3.1,'y'=>3.2,'r'=>3.3};
my $dot7 = {'x'=>4.1,'y'=>4.2,'r'=>4.3};
my $dot8 = {'x'=>5.1,'y'=>5.2,'r'=>5.3};

my $dotsA = [$dot1,$dot2];
my $dotsB = [$dot3,$dot4];
my $dotsC = [$dot5,$dot6];
my $dotsD = [$dot7,$dot8];

my $Ds = [$dotsA,$dotsB,$dotsC,$dotsD];
my $DDs = $Ds->[1]; #expect $dotsB

my $hsh = $DDs->[0]; #expect $dot3

say scalar @$DDs; #expect 2
say $hsh->{'x'};






您应该查看 perlreftut 现代Perl的嵌套数据结构一章

这篇关于Perl:数组和哈希的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆