我正在开发一个调用VMware vSphere perl API的perl脚本。我面临一些问题,谷歌搜索时,我找到了一个似乎对我有用的解决方案。但是,代码的一个重要部分是用map
编写的。感谢写入它的VMware社区成员。这是代码:
$datastore_map = map { $_->{'mo_ref'}->{'value'} => $_ } @{$datastore_views || [ ]};
我无法理解上述行正在做什么。
那么,你能帮助我将上面的行转换为foreach循环或类似的东西。相信TMTOWTDI,必须有另一种方法来编写相同的逻辑。
我多次尝试学习map
功能,但它总是从我脑海中反弹。因此,我想在不使用map
函数的情况下实现上述逻辑。
修改
阅读完答案后,我认为它应该是%datastore_map
而不是$datastore_map
。因为代码的下一行是$datastore = $datastore_map->{$moref->{'value'}};
这必须是一个错字。
当stacoverflow允许我时,我会接受答案。感谢您的快速回复。我花了差不多一个小时试图理解它并且失败了。
感谢。
修改
感谢@nickisfat,@ choroba和@ikegami的回复。所有答案都是正确的,但我只接受一个。所以我将按照按时间顺序首先发布的那个去。再次感谢您的回答。
答案 0 :(得分:4)
map BLOCK LIST
与
非常相似do {
my @list;
for (LIST) {
push @list, do BLOCK;
}
@list
};
您发布的代码毫无意义。赋值的LHS实际上是哈希,或者缺少一组curlies。假设您的代码实际上是
my $datastore_map = {
map { $_->{'mo_ref'}->{'value'} => $_ }
@{ $datastore_views || [ ] }
};
在我们开始之前,让我们将其重写为以下内容以使事情变得更简单。
my %datastore_map =
map { $_->{'mo_ref'}->{'value'} => $_ }
@{ $datastore_views || [ ] };
my $datastore_map = \%datastore_map;
这意味着你拥有的东西相当于
my %datastore_map = do {
my @list;
for (@{ $datastore_views || [ ] }) {
push @list, do { $_->{'mo_ref'}->{'value'} => $_ };
}
@list
};
my $datastore_map = \%datastore_map;
我们可以将其简化为
my %datastore_map;
for (@{ $datastore_views || [ ] }) {
$datastore_map{ $_->{'mo_ref'}->{'value'} } = $_;
}
my $datastore_map = \%datastore_map;
或
my %datastore_map;
if ($datastore_views) {
for (@$datastore_views) {
$datastore_map{ $_->{'mo_ref'}->{'value'} } = $_;
}
}
my $datastore_map = \%datastore_map;
答案 1 :(得分:1)
您确定要将结果分配给标量吗?
如果没有,请使用以下内容:
my %datastore_map;
for my $view (@$datastore_views) {
$datastore_map{$view->{mo_ref}{value}} = $view;
}
如果是,您希望获得的观看次数为2次。因此,请使用
$datastore_map = 2 * @$datastore_views;
但是,在这种情况下,选择的名称很糟糕。
答案 2 :(得分:1)
$ datastore_views是一个包含哈希值的数组,代码会创建一个哈希值($ datastore_map),这些哈希值是{'mo_ref'} - > {'value'}的内容。
在foreach中:
foreach my $item( @$datastore_views ){
$datastore_map->{ $item->{'mo_ref'}->{'value'} } = $item;
}
编辑:
或者至少那就是原始代码是:
%$datastore_map = map { $_->{'mo_ref'}->{'value'} => $_ } @{$datastore_views || [ ]};