2017-04-25 93 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