perl中的引用:数组的哈希到另一个数组

时间:2014-04-06 13:09:34

标签: arrays perl hash reference

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

    )
);

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

2 个答案:

答案 0 :(得分:0)

首先,你错过了一个引用:

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

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

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

或者在打印周期中使用值

执行任何操作

答案 1 :(得分:0)

您应该阅读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;
    }
}

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

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]->[$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:< / p>

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