[英]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}
- 来自特定国家的特定值 $x
从0
到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",
},
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.