Reputation: 23512
I am working on a perl script which calls VMware vSphere perl API. I was facing few problems and while googling, I found a solution which seems to work for me. However, one of the important piece of the code is written with map
. Credit goes to the VMware community member who wrote it. Here is the code:
$datastore_map = map { $_->{'mo_ref'}->{'value'} => $_ } @{$datastore_views || [ ]};
I am not able to understand what above line is doing.
So, Could you help me to convert above line into a foreach loop or something similar. Believing in TMTOWTDI, there has to be another way to write same logic.
I tried to learn the map
function a lot of times but it always bounces off my head. Hence I want to implement above logic without using the map
function.
EDIT:
After reading the answers, I think the it should be %datastore_map
and not $datastore_map
. Because the next line of the code is $datastore = $datastore_map->{$moref->{'value'}};
It has to be a typo.
I will accept the answer when stacoverflow allows me to. Thanks for the quick repsonces. I spend almost an hour trying to understand it and failed at it.
Thanks.
EDIT:
Thanks @nickisfat, @choroba and @ikegami for the responses. All the answers are correct but I can accept only one. So I will go with the one which was posted first in the chronological order. Thanks again for the answers.
Upvotes: 0
Views: 101
Reputation: 386216
map BLOCK LIST
is very similar to
do {
my @list;
for (LIST) {
push @list, do BLOCK;
}
@list
};
The code you posted makes no sense. Either the LHS of the assignment was actually a hash, or there's a set of curlies missing. Let's say your code is actually
my $datastore_map = {
map { $_->{'mo_ref'}->{'value'} => $_ }
@{ $datastore_views || [ ] }
};
Before we start, let's rewrite that to the following to make things a bit simpler.
my %datastore_map =
map { $_->{'mo_ref'}->{'value'} => $_ }
@{ $datastore_views || [ ] };
my $datastore_map = \%datastore_map;
So that means what you have is equivalent to
my %datastore_map = do {
my @list;
for (@{ $datastore_views || [ ] }) {
push @list, do { $_->{'mo_ref'}->{'value'} => $_ };
}
@list
};
my $datastore_map = \%datastore_map;
And we can simplify that to
my %datastore_map;
for (@{ $datastore_views || [ ] }) {
$datastore_map{ $_->{'mo_ref'}->{'value'} } = $_;
}
my $datastore_map = \%datastore_map;
or
my %datastore_map;
if ($datastore_views) {
for (@$datastore_views) {
$datastore_map{ $_->{'mo_ref'}->{'value'} } = $_;
}
}
my $datastore_map = \%datastore_map;
Upvotes: 4
Reputation: 5222
$datastore_views is an array containing hashes, the code creates a hash of those hashes ($datastore_map) keyed on the contents of {'mo_ref'}->{'value'}.
In foreach:
foreach my $item( @$datastore_views ){
$datastore_map->{ $item->{'mo_ref'}->{'value'} } = $item;
}
edit:
or at least thats what it would be doing if the original code was:
%$datastore_map = map { $_->{'mo_ref'}->{'value'} => $_ } @{$datastore_views || [ ]};
Upvotes: 1
Reputation: 241948
Are you sure you want to assing the result to a scalar?
If not, just use the following:
my %datastore_map;
for my $view (@$datastore_views) {
$datastore_map{$view->{mo_ref}{value}} = $view;
}
If yes, you want to get the number of views times 2. So, use simply
$datastore_map = 2 * @$datastore_views;
But, in such a case, the name of the variable is badly chosen.
Upvotes: 1