繁体   English   中英

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

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

我在将数组中的散列引用到另一个数组时遇到问题。 我有一个数组@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" },
);

我想将此数组划分为冒号并将@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;
 }
}

所以我需要的是,如果我打印出$part_col_all[0][0]{subject}结果将是"USA"

对于$part_col_all[1][0]{subject}将是"JPN"

对于$part_col_all[1][1]{operator}将是"+"等。

我对$part_col_all[0][0]{subject}"USA"

对于$part_col_all[0][1]{subject}"JPN" ,它应该在$part_col_all[1][0]{subject}

$part_col_all[0][3]{subject}"CHN" ,而它应该在 $part_col_all[1][2]{subject} 中。

我正在制作一个应用程序,它根据某个经济输入从经济数据创建图表。 @result 数组是我的预处理输入,我知道哪个变量属于哪个国家。 如果我得到像 GDP USA CAN、JPN+CHN 这样的输入,我需要将此输入拆分为 GDP USA CAN 和 JPN+CHN。 这就是为什么我做了一个条件,如果找到冒号,把@part_col 中的所有内容推送到@part_col_all 的第一个元素,然后如果它在输入的末尾,则将JPN+CHN 推送到@push_col_all 的第二个元素。

所以@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" },

    )
);

我不知道我做错了什么。 抱歉,如果有任何基本错误,我是初学者。 非常感谢。

首先,你缺少一个报价:

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

至于打印,您可以执行以下操作:

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

或者在打印周期中使用这些值做任何你想做的事情

您应该阅读Perl 参考教程来帮助您。

取消引用以简化您的代码并没有错:

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]
    }
}

请注意,我将for从您必须的三部分设置更改for更清晰、更易于理解的表述方式。

仔细观察您的数据结构,我注意到$hash{type}会告诉您是否定义了$hash{operator}$hash{subject}$hash{colon} 让我们只使用$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]
    }
}

事实上,由于@array只是一个数组,我会把它当作一个数组。 我将使用一个简单的for结构来遍历数组的每个元素。 每个元素都是一个 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;
    }
}

进一步简化,我可以使用->语法一次性取消引用并讨论我的哈希的特定元素:

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

我正在尝试了解您的其余代码:

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

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

这些@part_col@part_col_all让我困惑。 您到底想在@part_col_all存储@part_col_all 请记住, \\@part_col 是您在内存中存储@part_col 您一遍又一遍地将相同的内存位置推送到该哈希上,因此您一遍又一遍地存储相同的引用。 这真的是你想要的吗? 我对此表示怀疑。

您需要做的是确定您的数据结构究竟代表什么。 数据结构应该有一个可靠的定义。 @part_col_all的数据结构代表什么? $part_col_all[$i]的数据结构代表什么? $part_col_all[$i]->[$j]的数据结构代表什么? 如果不知道这一点,就很难回答您的其余问题。

您是否将类型为colon元素存储在一个数组中,并将其他所有元素存储在另一个数组中? 或者您是否将所有内容都存储在一个数组中,而在另一个数组中存储所有不是colon类型的内容?

一旦我明白了这一点,我就可以回答你的其余问题。

附录

感谢您的回复,我会尝试这种方式并写下我的结果。 这真的很有帮助。 我用有关@part_col_all 的数据结构的更多信息更新了我的问题。 我希望你能理解我要解释的内容,如果没有,我会再试一次。


如果我明白你在做什么,有人会输入NGDP USA , JPN+CNA这意味着你正在比较美国与日本和中国的 NGDP 总和。

在我看来,您需要三个单独的变量:

  • $parameter - 你在测量什么。 (GDP等)
  • @countries_set_1 - 第一组国家
  • @countries_set_2 - 您与第一组比较的第二组国家。

而且,你所说的冒号(我们在美国称之为逗号)作为第一组国家与第二组国家之间的分隔符。 然后,您只需通过一个循环即可。 可能两个数组只是同一个数组的两个元素,国家集合是数组引用。 我想象这样的事情:

@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;
}

这将创建一个这样的数据结构:

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

不需要复杂的@results因为您只需要为所有相关人员执行一个操作(GDP 等)。

不过,我想我明白你想要什么。 我们将使用一组数组。 这是我之前所拥有的:

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

我们将把它和我上面提供的将国家分成两组的代码结合起来:

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;
}

前几个条目将进入$country_sets[0] ,这将是一个数组引用。 冒号(不会被输入到集合中)之后,第二组国家将进入$country_sets[1] ,这将是另一个 array_ref 到哈希引用:

  • @country_sets - 将输入信息包含为两组
  • @country_sets[$x] - 一组特定的国家(可能还有运营商)
  • @country_sets[$x]->[$y] - 一个特定的国家或运营商
  • @country_sets[$x]->[$y]->{$key} - 来自特定国家的特定值

$x01 这会给你这样的东西:

$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