2012-11-01 54 views
0

我正在調用VMware vSphere perl API的perl腳本。我遇到了一些問題,並在Google上搜索時,發現了一個似乎適用於我的解決方案。但是,其中一個重要的代碼是用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

如果是這樣的下一行,你代碼應該是'my $ datastore_map = {map BLOCK LIST};'。調整我的節點。 (如果你問我,可能會添加一層間接尋址。) – ikegami

回答

4
map BLOCK LIST 

非常相似

do { 
    my @list; 
    for (LIST) { 
     push @list, do BLOCK; 
    } 
    @list 
}; 

您發佈的代碼沒有意義。無論是任務的LHS實際上是一個散列,或者缺少一組曲線。比方說,你的代碼實際上

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; 
+0

更新答案以補償OP中的更新。 – ikegami

+0

我同意我的代碼中的LHS是錯誤的。但是考慮下一行代碼:$ datastore = $ datastore_map - > {$ moref - > {'value'}};'我認爲LHS應該是'%$ datastore_map'而不是'%datastore_map'。呵呵!這是令人困惑的。 – slayedbylucifer

+0

'my $ datastore_map; %$ datastore_map = map BLOCK LIST;'你建議等於較短的'my $ datastore_map = {map BLOCK LIST};'我在更新中使用。我不喜歡你的版本,因爲它需要不必要的間接路線。 – ikegami

1

您確定要將結果分配給標量嗎?

如果沒有,只是使用以下命令:

my %datastore_map; 
for my $view (@$datastore_views) { 
    $datastore_map{$view->{mo_ref}{value}} = $view; 
} 

如果是的話,你想要得到的意見倍2.所以,數量,使用簡單

$datastore_map = 2 * @$datastore_views; 

但是,在這樣的情況下, ,該變量的名稱被嚴重選擇。

+0

如果我執行'print $ datastore_map',它會打印一個數字,所以是的,結果是一個標量。 – slayedbylucifer

+0

@Dheeraj:查看更新。 – choroba

+0

是的,你是對的,我錯了。謝謝。 – slayedbylucifer

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