不使用地图重写地图代码

时间:2012-11-01 09:45:24

标签: perl

我正在开发一个调用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的回复。所有答案都是正确的,但我只接受一个。所以我将按照按时间顺序首先发布的那个去。再次感谢您的回答。

3 个答案:

答案 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 || [ ]};