简体   繁体   English

perl 中的引用:数组到另一个数组的散列

[英]references in perl: hash of array to another array

I have a problem with referencing a hash in an array to another array.我在将数组中的散列引用到另一个数组时遇到问题。 I have an array @result which looks like this:我有一个数组@result,它看起来像这样:

@result = (

{ "type" => "variable",
  "s" => "NGDP",
  "variable" => "NGDP" },

{"type" => "subject",
  "s" => "USA",
  "subject" => "USA",
  "variable" => "NGDP" },

{ "type" => "colon",
  "s" => ",",
  "colon" => "," }, 

{ "type" => "subject",
  "s" => "JPN",
  "subject" => "JPN",
  "variable" => "NGDP" },

{ "type" => "operator",
  "s" => "+",
  "operator => "+" },

{"type" => "subject",
  "s" => "CHN",
  "subject" => "CHN",
  "variable" => "NGDP" },
);

I want to divide this array into colons and push elements of the @result array to another array, so i wrote the script:我想将此数组划分为冒号并将@result 数组的元素推送到另一个数组,因此我编写了脚本:

for ($i = 0; $i <= $#result; $i++) {  

if (defined $result[$i]{subject} or $result[$i]{operator} and not defined $result[$i]{colon}) {
  push @part_col, \%{$result[$i]};
}

elsif ($i == $#result) {
  push @part_col_all, \@part_col;
}

elsif (defined $result[$i]{colon}) {
  push @part_col_all, \@part_col;
  my @part_col;
 }
}

So what I need is that if I print out $part_col_all[0][0]{subject} the result will be "USA" ,所以我需要的是,如果我打印出$part_col_all[0][0]{subject}结果将是"USA"

and for $part_col_all[1][0]{subject} will be "JPN" ,对于$part_col_all[1][0]{subject}将是"JPN"

and for $part_col_all[1][1]{operator} will be "+" etc.对于$part_col_all[1][1]{operator}将是"+"等。

My result for $part_col_all[0][0]{subject} is "USA"我对$part_col_all[0][0]{subject}"USA"

and for $part_col_all[0][1]{subject} is "JPN" which should be in $part_col_all[1][0]{subject} .对于$part_col_all[0][1]{subject}"JPN" ,它应该在$part_col_all[1][0]{subject}

The result for $part_col_all[0][3]{subject} is "CHN" , while it should be in $part_col_all[1][2]{subject}. $part_col_all[0][3]{subject}"CHN" ,而它应该在 $part_col_all[1][2]{subject} 中。

I'm making an application which is creating graphs from economical data based on a certain economical input.我正在制作一个应用程序,它根据某个经济输入从经济数据创建图表。 The @result array is my preprocessed input where I know to which country which variable belongs. @result 数组是我的预处理输入,我知道哪个变量属于哪个国家。 If I get an input like GDP USA CAN, JPN+CHN I need to split this input to GDP USA CAN and JPN+CHN.如果我得到像 GDP USA CAN、JPN+CHN 这样的输入,我需要将此输入拆分为 GDP USA CAN 和 JPN+CHN。 That's why I made a condition, if colon is found, push everything in @part_col to the first element of @part_col_all, and then if it's on the end of the input, push JPN+CHN to the second element of @push_col_all.这就是为什么我做了一个条件,如果找到冒号,把@part_col 中的所有内容推送到@part_col_all 的第一个元素,然后如果它在输入的末尾,则将JPN+CHN 推送到@push_col_all 的第二个元素。

So @part_col_all should looks like this:所以@part_col_all 应该是这样的:

@part_col_all = (
    (   
        {"type" => "subject",
        "s" => "USA",
        "subject" => "USA",
        "variable" => "NGDP" },

        {"type" => "subject",
        "s" => "CAN",
        "subject" => "CAN",
        "variable" => "NGDP" },
    ),

    (
        { "type" => "subject",
        "s" => "JPN",
        "subject" => "JPN",
        "variable" => "NGDP" },

        { "type" => "operator",
        "s" => "+",
        "operator" => "+" },

        {"type" => "subject",
        "s" => "CHN",
        "subject" => "CHN",
        "variable" => "NGDP" },

    )
);

I dont know what I'm doing wrong.我不知道我做错了什么。 Sorry if there are any basic mistakes, im a beginner.抱歉,如果有任何基本错误,我是初学者。 Thanks a lot.非常感谢。

First, you're missing a quote:首先,你缺少一个报价:

{ "type" => "operator",
  "s" => "+",
  "operator" => "+" },
           ^ missing

As for printing, you can do the following:至于打印,您可以执行以下操作:

foreach my $part (@part_col){
    print $part->{operator}."\n";
}

Or do whatever you want in the print cycle with the values或者在打印周期中使用这些值做任何你想做的事情

You should read the Perl Reference Tutorial to help you.您应该阅读Perl 参考教程来帮助您。

There's no sin in dereferencing to simplify your code:取消引用以简化您的代码并没有错:

my @part_col;
my @part_col_all;

for $i ( 0..$#array ) {
    my %hash = ${ $result[$i] };  # Make it easy on yourself. Dereference
    if ( defined $hash{subject} or defined $hash{operator} and not defined $hash{colon} ) {
        push @part_col, \%hash;  # or push, @par_col, $result[$i]
    }
}

Notice I changed the for from the three part setup you had to a cleaner and easier to understand way of stating it.请注意,我将for从您必须的三部分设置更改for更清晰、更易于理解的表述方式。

Looking closer at your data structure, I notice that $hash{type} will tell you whether or not $hash{operator} , $hash{subject} , or $hash{colon} is defined.仔细观察您的数据结构,我注意到$hash{type}会告诉您是否定义了$hash{operator}$hash{subject}$hash{colon} Let's just use $hash{type} and simplify that if :让我们只使用$hash{type}并简化它, if

my @part_col;
my @part_col_all;

for my $i ( 0..$#array ) { 
    my %hash = ${ $result[$i] };  # Make it easy on yourself. Dereference
    if ( $hash{type} eq "subject" or $hash{type} eq "operator" ) {
        push @part_col, \%hash;  # or push, @par_col, $result[$i]
    }
}

In fact, since @array is just an array, I'll treat it like one.事实上,由于@array只是一个数组,我会把它当作一个数组。 I'll use a simple for structure to go through each element of my array.我将使用一个简单的for结构来遍历数组的每个元素。 Each element is a hash_reference, so:每个元素都是一个 hash_reference,所以:

for my $hash_ref ( @array ) {
    my %hash = %{ %hash_ref };
    if ( $hash{type} eq "subject" or $hash{type} eq "operator" ) {
        push @part_col, \%hash;
    }
}

And further simplification, I can dereference and talk about a particular element of my hash all at once by using the -> syntax:进一步简化,我可以使用->语法一次性取消引用并讨论我的哈希的特定元素:

for my $hash_ref ( @array ) {
    if ( $hash_ref->{type} eq "subject" or $hash_ref->{type} eq "operator" ) {
        push @part_col, $hash_ref;
    }
}

I'm trying to understand the rest of your code:我正在尝试了解您的其余代码:

    elsif ($i == $#result) {
        push @part_col_all, \@part_col;
    }

    elsif (defined $hash_ref->{colon}) {
        push @part_col_all, \@part_col;
        my @part_col;
    }
}

These pushes of @part_col onto @part_col_all confuse me.这些@part_col@part_col_all让我困惑。 Exactly what are you trying to store in @part_col_all ?您到底想在@part_col_all存储@part_col_all Remember that \\@part_col is the location in memory where you're storing @part_col .请记住, \\@part_col 是您在内存中存储@part_col You're pushing that same memory location over and over onto that hash, so you're storing the same reference over and over again.您一遍又一遍地将相同的内存位置推送到该哈希上,因此您一遍又一遍地存储相同的引用。 Is that really what you want?这真的是你想要的吗? I doubt it.我对此表示怀疑。

You need to do is to decide exactly what your data structure really represents.您需要做的是确定您的数据结构究竟代表什么。 A data structure should have a solid definition.数据结构应该有一个可靠的定义。 What does the data structure @part_col_all represent? @part_col_all的数据结构代表什么? What does the data structure $part_col_all[$i] represent? $part_col_all[$i]的数据结构代表什么? What does the data structure $part_col_all[$i]->[$j] represent? $part_col_all[$i]->[$j]的数据结构代表什么? Without knowing this, it's very hard to answer the rest of your question.如果不知道这一点,就很难回答您的其余问题。

Are you storing elements where the type is colon in one array and everything else in another array?您是否将类型为colon元素存储在一个数组中,并将其他所有元素存储在另一个数组中? Or are you storing everything in one array, and in another array, storing everything that's not a type colon ?或者您是否将所有内容都存储在一个数组中,而在另一个数组中存储所有不是colon类型的内容?

Once I understand this, I can answer the rest of your question.一旦我明白了这一点,我就可以回答你的其余问题。

Addendum附录

Thank you for your reply, I will try that way and write my results.感谢您的回复,我会尝试这种方式并写下我的结果。 It is realy helpful.这真的很有帮助。 I updated my question with more information about data structure of @part_col_all.我用有关@part_col_all 的数据结构的更多信息更新了我的问题。 I hope that you understand what I'm trying to explain, if not I'll try it again.我希望你能理解我要解释的内容,如果没有,我会再试一次。


If I understand what you're doing, someone enters in NGDP USA , JPN+CNA and that means you're comparing the NGDP between the United States vs. Japan and China combined.如果我明白你在做什么,有人会输入NGDP USA , JPN+CNA这意味着你正在比较美国与日本和中国的 NGDP 总和。

It seems to me that you would want three separate variables:在我看来,您需要三个单独的变量:

  • $parameter - What you are measuring. $parameter - 你在测量什么。 (GDP, etc.) (GDP等)
  • @countries_set_1 - The first set of countries @countries_set_1 - 第一组国家
  • @countries_set_2 - The second set of countries which you're comparing against the first set. @countries_set_2 - 您与第一组比较的第二组国家。

And, what you call the colon (which we would call a comma in the US) as a separator between the first set of countries vs. the second set.而且,你所说的冒号(我们在美国称之为逗号)作为第一组国家与第二组国家之间的分隔符。 Then, you'd simply go through a loop.然后,您只需通过一个循环即可。 It could be that the two arrays are merely two elements of the same array, and the sets of countries are array references.可能两个数组只是同一个数组的两个元素,国家集合是数组引用。 I imagine something like this:我想象这样的事情:

@input = qw(GDP USA, JPN CHN); # Compare the GDP of the USA with Japan and China together
my $parameter = shift @input;  # Remove what you're measuring
my @country_sets;              # An array of arrays
my $set = 0                    # Which set you're on
for my $value ( @input ) {
    if ( $value eq "," ) {
       $set += 1;              # Next Set
       next;
    }
    push @{ $country_sets[$set] }, $input;
}

This would create a data structure like this:这将创建一个这样的数据结构:

@country_sets  = (
                     (
                          USA,
                     ),
                     (
                          JPN,
                          CHN,
                     ),
                 )

No need for the complex @results since you're only going to have a single operation (GDP, etc.) for all involved.不需要复杂的@results因为您只需要为所有相关人员执行一个操作(GDP 等)。

However, I think I see what you want.不过,我想我明白你想要什么。 We'll go with an array of arrays.我们将使用一组数组。 Here's what I had before:这是我之前所拥有的:

for my $hash_ref ( @array ) {
    if ( $hash_ref->{type} eq "subject" or $hash_ref->{type} eq "operator" ) {
        push @part_col, $hash_ref;
    }
}

We'll combine that and the code I offered right above which splits the countries into two sets:我们将把它和我上面提供的将国家分成两组的代码结合起来:

my @country_sets;              # An array of arrays
my $set = 0                    # Which set you're on
for my $country_ref ( @array ) {
    next if $country_ref->{type} eq "variable";  # We don't want variables
    if ( $country_ref{type} eq "colon" ) {       # Switch to the other country set
        set += 1;
        next;
    }
    push @{ $country_sets[$set] }, $country_ref;
}

The first few entries will go into $country_sets[0] which will be an array reference.前几个条目将进入$country_sets[0] ,这将是一个数组引用。 After the colon (which won't be input into the set), the second set of countries will go into $country_sets[1] which will be an other array_ref to a reference of hashes:冒号(不会被输入到集合中)之后,第二组国家将进入$country_sets[1] ,这将是另一个 array_ref 到哈希引用:

  • @country_sets - Contains the input information into two sets @country_sets - 将输入信息包含为两组
  • @country_sets[$x] - A particular set of countries (and possibly operator) @country_sets[$x] - 一组特定的国家(可能还有运营商)
  • @country_sets[$x]->[$y] - A Particular country or operator @country_sets[$x]->[$y] - 一个特定的国家或运营商
  • @country_sets[$x]->[$y]->{$key} - A particular value from a particular country @country_sets[$x]->[$y]->{$key} - 来自特定国家的特定值

Where $x goes from 0 to 1 . $x01 This will give you something like this:这会给你这样的东西:

$country_sets[0] = (
                       {
                          "type" => "subject",
                          "s" => "USA",
                           "subject" => "USA",
                           "variable" => "NGDP",
                       },
                   )

$country_sets[1] = (
                      {
                         "type" => "subject",
                         "s" => "JPN",
                         "subject" => "JPN",
                         "variable" => "NGDP",
                      },

                      { 
                          "type" => "operator",
                          "s" => "+",
                          "operator => "+",
                      },
                      {
                          "type" => "subject",
                          "s" => "CHN",
                          "subject" => "CHN",
                          "variable" => "NGDP",
                      },
                 );

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

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