简体   繁体   English

了解Perl数组中的引用以及如何访问数据

[英]Understanding referencing within perl arrays and how data is accessed

I could do with some help on perl and how it handles its arrays. 我可以在perl及其如何处理其数组方面提供一些帮助。 (A long time ago) I used to do quite a lot of coding (hacking would be a better description, never pretty work) using php, java, js, etc but for various reasons I'm using perl for a project and i'm struggling to work out why I'm finding arrays such a pain. (很久以前)我曾经使用php,java,js等做过很多编码(黑客会是一个更好的描述,永远不会做得很好),但是由于种种原因,我在项目中使用了perl,我正在努力找出为什么我很难找到数组。

For example, the following code: 例如,以下代码:

@inflightsequences=([1,6,[["SRCIP","1.2.3.4"],["DSTIP","5.6.7.8"]]],[2,2,[["SRCIP","1.2.3.4"],["DSTIP","5.6.7.8"]]]);

foreach (@inflightsequences) {print Dumper @_};

where the definition of the array creates this (printed using Dumper) 数组的定义在哪里创建(使用Dumper打印)

$VAR1 = [
      1,
      6,
      [
        [
          'SRCIP',
          '1.2.3.4'
        ],
        [
          'DSTIP',
          '5.6.7.8'
        ]
      ]
    ];

$VAR2 = [
      2,
      2,
      [
        [
          'SRCIP',
          '1.2.3.4'
        ],
        [
          'DSTIP',
          '5.6.7.8'
        ]
      ]
    ];

(NB I'll refer to the data inside the array using VAR1 and VAR2 from now on so its clear which block I'm referring to, regardless of whether thats actually what Dumper calls it) (注意,从现在开始,我将使用VAR1和VAR2引用数组中的数据,因此无论Dumper实际调用的是什么,它都清楚我要引用哪个块)

...but the foreach outputs absolutely nothing, when I expected it to cycle twice and output whats in VAR1 first then in VAR2. ...但是当我希望它循环两次并先在VAR1中然后在VAR2中输出内容时,foreach绝对不会输出任何内容。 However 然而

print Dumper @inflightsequences[0];
print Dumper @inflightsequences[1];

does print out VAR1 and VAR2 as expected. 确实按预期打印出VAR1和VAR2。

Then I extract the first item from the @inflightsequences array 然后我从@inflightsequences数组中提取第一项

@dataset = shift(@inflightsequences);

and I expected print $dataset[1] to print out the first value (1) in what was VAR1 and print $dataset[2] to print the second value (6) but no, to achieve what I expected I have to do print $dataset[0][0] and print $dataset[0][1] . 我希望print $dataset[1]在VAR1中打印出第一个值(1),而print $dataset[2]打印第二个值(6),但没有,要达到我期望的print $dataset[0][0]print $dataset[0][1] Why the extra [0]? 为什么要多加[0]?

And thus I have got myself completely confused.... 因此,我感到非常困惑。

Thanks 谢谢

--Chris - 克里斯

@inflightsequences is an array of array references so @inflightsequences是数组引用的数组,因此

$r=shift(@inflightsequences)

print $r->[0]

will show 1 将显示1

and

print $r->[1]

will show 6 将显示6

doing 在做

@dataset=shift(@inflightsequences)

Makes an array from the result from the shift. 根据移位的结果制作一个数组。 So it's a array with one element, the shift result, which is accessed as $dataset[0]. 因此,它是一个包含一个元素的数组,即移位结果,可通过$ dataset [0]进行访问。 $dataset[0]->[1] will give 6, for example $ dataset [0]-> [1]将给出6,例如

What is confusing you is that the elements of Perl arrays are always scalar values. 使您感到困惑的是,Perl数组的元素始终是量值。 You make arrays of arrays by using references for those scalars. 您可以通过使用标量的引用来创建数组的数组。

You can create an array reference either by building a named array and taking its reference 您可以通过建立命名数组并获取其引用来创建数组引用

my @data = ( 'a', 'b', 'c' );
my $array_ref = \@data;

or by creating an anonymous array 或通过创建匿名数组

my $array_ref = [ 'a', 'b', 'c' ];

The only difference between these two is that the data can be accessed through the name @data in the first case as well as through the reference $array_ref . 两者之间的唯一区别是,在第一种情况下,可以通过名称@data以及引用$array_ref来访问数据。 To access elements of an array through a reference, you use the arrow operator, so 要通过引用访问数组的元素,请使用箭头运算符,因此

$array_ref->[0]

is the same as 是相同的

$data[0]

The reason your foreach loop prints nothing is that you are dumping the contents of the array @_ which you have never mentioned before and is empty. foreach循环不输出任何内容的原因是,您正在转储@_数组的内容,该内容以前从未提到过,并且为空。 @_ is the array that is set within a subroutine to the actual parameters passed when that subroutine is called. @_是在子例程中设置为调用该子例程时传递的实际参数的数组。 It has no use otherwise. 否则它没有用。

Remembering that array elements are scalars , and that if you don't specify a loop control variable then Perl will use $_ , what you should have written is 记住数组元素是标量 ,并且如果您不指定循环控制变量,那么Perl将使用$_ ,您应该写的是

foreach (@inflightsequences) { print Dumper($_) }

or, more Perlishly, 或更确切地说,

print Dumper($_) for @inflightsequences

The same applies to your statement 同样适用于您的陈述

@dataset = shift(@inflightsequences)

which, again, because the contents of @inflightsequences are scalars is removing the first array reference and putting it into @dataset , which is now just a one-element array containing an array reference. 同样,由于@inflightsequences的内容是标量,因此将删除第一个数组引用并将其放入@dataset ,该数据集现在只是一个包含数组引用的单元素数组。 That means you have moved $inflightsequences[0] to $dataset[0] , which is now equal to 这意味着您已经将$inflightsequences[0]移至$dataset[0] ,现在等于

[1, 6, [ ["SRCIP", "1.2.3.4"], ["DSTIP", "5.6.7.8"] ] ]

not forgetting that the square brackets create a reference to an anonymous array. 不要忘了括号创建了对匿名数组的引用。 So, like our $array_ref->[0] above, you can access the first element of this array using $dataset[0]->[0] . 因此,就像上面的$array_ref->[0] ,您可以使用$dataset[0]->[0]访问该数组的第一个元素。 And because Perl allows you to remove the arrow operator between pairs of square brackets (and curly brackets if we're using hashes) you can contract that to $dataset[0][0] which happens to be the value 1. 而且由于Perl允许您删除成对的方括号(如果使用哈希,则使用大括号)之间的箭头运算符,因此可以将其收缩为$dataset[0][0] ,该值恰好是值1。

I hope that helps. 希望对您有所帮助。 You would do well to read perlref and experiment a little. 您最好阅读perlref并进行一些实验。 Note that the Data::Dump module produces output much superior to Data::Dumper , but you may need to install it as it isn't a core module. 注意, Data::Dump模块产生的输出要比Data::Dumper更好,但是您可能需要安装它,因为它不是核心模块。 Once it's installed the code will look like 一旦安装,代码将如下所示

use Data::Dump;

dd \@inflightsequences;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM