2017-04-25 123 views
2

我確信標題不是很清楚,爲此我表示歉意。我遇到了一個我正在編寫的腳本的一個問題,我希望能夠幫助您弄清楚發生了什麼。我想通了如何解決這個問題,我更期待爲什麼這種情況正在發生。腳本長度超過3k行,但我在下面寫的片段重現了同樣的問題。PowerShell哈希表值從循環外的第二個哈希表中刪除

我有三個哈希表,DeviceList,AllDevices和RemovedDevices。 Devicelist是明確的,AllDevices等於DeviceList。在循環中,RemovedDevices中存在的項從DeviceList中刪除。儘管AllDevices僅在本示例的開始處進行了修改,但設備仍在被刪除。

$DeviceList = @{"server1" = "email1"; "server2" = "email2"; "server3" = "email3"} 
$AllDevices = $DeviceList 
$RemovedDevices = @{"server1" = "email1"; "server2" = "email2"} 

foreach($RemovedDevice in $RemovedDevices.GetEnumerator()) 
    { 
    $DeviceList | where {$_.ContainsKey($RemovedDevice.Key)} | % {$_.Remove($RemovedDevice.Key)} 
    } 
$AllDevices 

運行上述文本,$ AllDevices被修改爲僅包含server3 info,它仍應包含所有3個服務器。

如果我修改第二行:

$AllDevices += $DeviceList 

然後AllDevices維護所有3個值。通過使用斷點並逐步完成第一個版本,我證實AllDevices在第一次之後沒有被擊中。

我的整體問題是:爲什麼AllDevices在循環結束後被修改爲等於DeviceList?如果在開始時只調用一次,不管它是否保持靜態,儘管對DeviceList進行了修改?使用類似的方法重建數組不會覆蓋AllDevices,所以我想這是一個散列表怪癖。

PSVersion 5.0.10586.117

回答

4

爲什麼AllDevices被修正爲等於DEVICELIST循環完成後?

因爲$AllDevices僅僅是一個參考相同的底層對象$DeviceList

如果它在一開始只叫一次,應該不是它的值保持不變,儘管修改DEVICELIST?

如果$AllDevices是一個相同對象,肯定的,但它不只是相同的 - 這是同一個對象。

幸運的是,是散列表實現ICloneable接口,因此對於淺哈希表,你可以使用Clone()方法:

$DeviceList = @{"server1" = "email1"; "server2" = "email2"; "server3" = "email3"} 
$AllDevices = $DeviceList.Clone() 

$RemovedDevices = @{"server1" = "email1"; "server2" = "email2"} 

foreach($RemovedDevice in $RemovedDevices.GetEnumerator()) 
{ 
    if($DeviceList.ContainsKey($RemovedDevice.Key)) 
    { 
     $DeviceList.Remove($RemovedDevice.Key) 
    } 
} 
$AllDevices 

我發現了一個哈希表的使用與Where-Object超級不可讀(更不用說不必要的慢) ,但功能上是一樣的你原來foreach循環體

+0

我從來不知道做這樣的說法,這只是一個參考,而不是一個單獨的對象。非常感謝您的解釋! – Nick