Perl 将数组添加到无引用数组的哈希中
我正在使用API获取信息并将其保存到文件中Perl 将数组添加到无引用数组的哈希中,perl,Perl,我正在使用API获取信息并将其保存到文件中 #!/bin/perl use strict; use warnings; use JSON; use Data::Dumper; my %Hash; my @Array; my $url = "https://foo/bar" my $apidata = `/usr/bin/curl -k -u $url` my $apidatajson = decode_json $apidata; my $i=0; foreach(@{
#!/bin/perl
use strict;
use warnings;
use JSON;
use Data::Dumper;
my %Hash;
my @Array;
my $url = "https://foo/bar"
my $apidata = `/usr/bin/curl -k -u $url`
my $apidatajson = decode_json $apidata;
my $i=0;
foreach(@{ $apidatajson->{category} }){
@Array=();
my $Name=$apidatajson->{category}[$i]{Name};
my $value=$apidatajson->{category}[$i]{Value};
push(@Array,($Name,$value));
$Hash{$Name}=@Array; # Output 1
$Hash{$Name}=\@Array; # Output 2
$i++;
}
print Dumper \%Hash;
输出1如下所示:
$VAR1{
"FooName2" => 2;
"FooName" => 2;
};
$VAR1{
"FooName2" => [
"FooName2"
"FooValue2"
]
"FooName" => $VAR1 -> {'FooName2'}
};
$VAR1 {
"FooName2" => [
"FooName2"
"FooValue2"
]
"FooName" => [
"FooName"
"FooValue"
]
}
输出2如下所示:
$VAR1{
"FooName2" => 2;
"FooName" => 2;
};
$VAR1{
"FooName2" => [
"FooName2"
"FooValue2"
]
"FooName" => $VAR1 -> {'FooName2'}
};
$VAR1 {
"FooName2" => [
"FooName2"
"FooValue2"
]
"FooName" => [
"FooName"
"FooValue"
]
}
我需要它看起来像这样:
$VAR1{
"FooName2" => 2;
"FooName" => 2;
};
$VAR1{
"FooName2" => [
"FooName2"
"FooValue2"
]
"FooName" => $VAR1 -> {'FooName2'}
};
$VAR1 {
"FooName2" => [
"FooName2"
"FooValue2"
]
"FooName" => [
"FooName"
"FooValue"
]
}
因此,本质上我要问的是,如何在不使用引用的情况下将数组的内容保存在散列中,这样它就不会弄乱除最后一个之外的所有条目?尝试以下方法:
$Hash{$Name}=[$Name, $value];
方括号是Perl中的数组引用
如果需要,您不能避免数组引用。你的要求是矛盾的
顺便说一句:您在第二个版本中创建的是循环引用。可能是因为全局和局部范围中的变量名相同。但我认为输出不属于您的代码。尝试以下方法:
$Hash{$Name}=[$Name, $value];
方括号是Perl中的数组引用
如果需要,您不能避免数组引用。你的要求是矛盾的
顺便说一句:您在第二个版本中创建的是循环引用。可能是因为全局和局部范围中的变量名相同。但是我认为输出不属于您的代码。您问题中的代码不是您正在运行的代码。特别是,我怀疑您没有行
my@Array=()
,而是@Array=()
(没有my
)
因此,$Hash{$Name}=\@Array
引用在foreach
循环外部声明的数组(因为循环中实际上没有声明任何数组),这就是哈希表的两个值相同的原因
如果在循环中声明@Array
,则代码工作正常
补充说明:
- 您的代码似乎混淆了“foreach”循环和C风格for循环。您的循环应该是:
或者,由于您实际上不需要for (@{ $apidatajson->{category}}){ my @Array; my $Name = $_->{Name}; my $value = $_->{Value}; push(@Array,($Name,$value)); $Hash{$Name} = \@Array; }
,只需:@Array
或者,如果您需要保留for (@{ $apidatajson->{category}}){ my $Name = $_->{Name}; my $value = $_->{Value}; $Hash{$Name} = [$Name, $value]; }
:$i
for my $i (0 .. $#{$apidatajson->{category}}) { my $Name = $apidatajson->{category}[$i]{Name}; my $value = $apidatajson->{category}[$i]{Value}; $Hash{$Name} = [$Name, $value]; }
- 您不需要调用
来执行http请求。相反,您可以使用Perl模块,如:curl
- 您问题中的代码不是您正在运行的代码。特别是,我怀疑您没有行
my@Array=()
,而是@Array=()
(没有my
)
因此,$Hash{$Name}=\@Array
引用在foreach
循环外部声明的数组(因为循环中实际上没有声明任何数组),这就是哈希表的两个值相同的原因
如果在循环中声明@Array
,则代码工作正常
补充说明:
- 您的代码似乎混淆了“foreach”循环和C风格for循环。您的循环应该是:
或者,由于您实际上不需要for (@{ $apidatajson->{category}}){ my @Array; my $Name = $_->{Name}; my $value = $_->{Value}; push(@Array,($Name,$value)); $Hash{$Name} = \@Array; }
,只需:@Array
或者,如果您需要保留for (@{ $apidatajson->{category}}){ my $Name = $_->{Name}; my $value = $_->{Value}; $Hash{$Name} = [$Name, $value]; }
:$i
for my $i (0 .. $#{$apidatajson->{category}}) { my $Name = $apidatajson->{category}[$i]{Name}; my $value = $apidatajson->{category}[$i]{Value}; $Hash{$Name} = [$Name, $value]; }
- 您不需要调用
来执行http请求。相反,您可以使用Perl模块,如:curl
foreach
的行中缺少一个}
。此外,您的代码没有重现您所讨论的问题(可能是因为您在循环中的@Array=()
之前添加了my
)。最后,在curl https:/foo/bar
周围使用双引号而不是反勾号。下一次,请在发布问题之前测试您的代码。(刚刚意识到我之前的评论听起来有点刺耳,我希望如此):您在发布之前简化代码是正确的,我们对此表示感谢。下次,只需在简化后和发布之前在本地运行它;)无论如何,欢迎使用StackOverflow。您在foreach
的行中缺少一个}
。此外,您的代码没有重现您所讨论的问题(可能是因为您在循环中的@Array=()
之前添加了my
)。最后,在curl https:/foo/bar
周围使用双引号而不是反勾号。下一次,请在发布问题之前测试您的代码。(刚刚意识到我之前的评论听起来有点刺耳,我希望如此):您在发布之前简化代码是正确的,我们对此表示感谢。下次,只需在简化后和发布之前在本地运行它;)无论如何,欢迎来到StackOverflow。我想你可能也会对for
和foreach
之间的区别感到困惑。Perl不关心循环使用哪个名称,只关心paren中的名称。和foreach
的名称可以互换。类似于for(@list)
的内容将导致foreach循环,类似于foreach(my$i=0;$i<$n;+$i)
的内容将导致for循环。不同之处在于foreach将隐式地本地化先前声明的迭代变量,因此一旦循环退出,它将恢复到它在循环外的值。@Silvar我很清楚for
和foreach
是可互换的。然而,说“你似乎混淆了for和for”似乎不如说“你似乎混淆了foreach和c-style for”。此外,如果您查看,您会注意到术语“foreach”和“C-style for”的使用方式与我的答案中的相同。@Silvar此外,我的答案中关于for循环的注释不是关于“for vs foreach”,而是关于执行my$i=0;对于(@array){f($array[$i]);$i++}
而不是(@array){f($)}的。我要说的是,任何做前者的人都忽略了foreach厕所的意义