【问题标题】:references in perl: hash of array to another arrayperl中的引用:数组的哈希到另一个数组
【发布时间】:2014-05-18 15:17:26
【问题描述】:

我在将数组中的哈希引用到另一个数组时遇到问题。 我有一个数组@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} 将是"+" 等等。

我对@9​​87654329@ 的结果是"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" },

    )
);

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

【问题讨论】:

    标签: arrays perl hash reference


    【解决方案1】:

    首先,您缺少报价:

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

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

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

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

    【讨论】:

      【解决方案2】:

      您应该阅读Perl Reference Tutorial 来帮助您。

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

      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 从您必须的三部分设置更改为更简洁、更易于理解的表述方式。

      仔细观察您的数据结构,我注意到$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;
          }
      }
      

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

      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 是您在内存中存储@part_col 的位置。您一遍又一遍地将相同的内存位置推送到该哈希上,因此您一遍又一遍地存储相同的引用。这真的是你想要的吗?我怀疑。

      您需要做的是确定您的数据结构真正代表什么。数据结构应该有一个可靠的定义。数据结构@part_col_all代表什么?数据结构$part_col_all[$i]代表什么?数据结构$part_col_all[$i]-&gt;[$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]-&gt;[$y] - 特定国家或运营商
      • @country_sets[$x]-&gt;[$y]-&gt;{$key} - 来自特定国家/地区的特定值

      $x0 变为1。这会给你这样的东西:

      $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",
                            },
                       );
      

      【讨论】:

      • 感谢您的回复,我会尝试这样写我的结果。这真的很有帮助。我用有关@part_col_all 的数据结构的更多信息更新了我的问题。我希望您能理解我要解释的内容,否则我会再试一次。
      猜你喜欢
      • 2011-07-26
      • 2019-07-30
      • 1970-01-01
      • 2016-06-06
      • 1970-01-01
      • 2011-07-02
      • 1970-01-01
      • 1970-01-01
      • 2016-08-06
      相关资源
      最近更新 更多