从循环外的第二个哈希表中删除 PowerShell 哈希表值
PowerShell Hashtable values being removed from second hashtable outside of loop
我确定标题不是很清楚,为此我深表歉意。我 运行 遇到了一个我正在编写的脚本的问题,希望得到一些帮助来弄清楚发生了什么。我想出了解决问题的方法,我更想知道 为什么 会发生这种情况。脚本超过 3k 行,但我在下面写的代码片段重现了同样的问题。
我有三个哈希表,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 信息,它应该仍然包含所有 3 个服务器。
如果我修改第二行为:
$AllDevices += $DeviceList
然后 AllDevices 维护所有 3 个值。使用断点并单步执行第一个版本,我已验证 AllDevices 在第一次后没有被命中。
我的总体问题是:为什么在循环结束后将 AllDevices 修改为等于 DeviceList?如果一开始只调用一次,那么尽管对 DeviceList 进行了修改,它的值不应该保持静态吗?使用类似的方法重建数组不会覆盖 AllDevices 所以我想这是一个哈希表怪癖。
PS 版本 5.0.10586.117
Why is AllDevices being modified to equal DeviceList after the loop has finished?
因为 $AllDevices
只是 对与 $DeviceList
相同的底层对象的引用
If it's only called once at the beginning, shouldn't it's value remain static despite modifications to 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
循环体相同
我确定标题不是很清楚,为此我深表歉意。我 运行 遇到了一个我正在编写的脚本的问题,希望得到一些帮助来弄清楚发生了什么。我想出了解决问题的方法,我更想知道 为什么 会发生这种情况。脚本超过 3k 行,但我在下面写的代码片段重现了同样的问题。
我有三个哈希表,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 信息,它应该仍然包含所有 3 个服务器。
如果我修改第二行为:
$AllDevices += $DeviceList
然后 AllDevices 维护所有 3 个值。使用断点并单步执行第一个版本,我已验证 AllDevices 在第一次后没有被命中。
我的总体问题是:为什么在循环结束后将 AllDevices 修改为等于 DeviceList?如果一开始只调用一次,那么尽管对 DeviceList 进行了修改,它的值不应该保持静态吗?使用类似的方法重建数组不会覆盖 AllDevices 所以我想这是一个哈希表怪癖。
PS 版本 5.0.10586.117
Why is AllDevices being modified to equal DeviceList after the loop has finished?
因为 $AllDevices
只是 对与 $DeviceList
If it's only called once at the beginning, shouldn't it's value remain static despite modifications to 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
循环体相同