I'm trying to loop through a hash table and set the value of each key to 5 and Powershell gives an error:
我试图遍历哈希表并将每个键的值设置为5,Powershell给出错误:
$myHash = @{}
$myHash["a"] = 1
$myHash["b"] = 2
$myHash["c"] = 3
foreach($key in $myHash.keys){
$myHash[$key] = 5
}
An error occurred while enumerating through a collection:
通过集合枚举时发生错误:
Collection was modified; enumeration operation may not execute..
At line:1 char:8
+ foreach <<<< ($key in $myHash.keys){
+ CategoryInfo : InvalidOperation: (System.Collecti...tableEnumer
ator:HashtableEnumerator) [], RuntimeException
+ FullyQualifiedErrorId : BadEnumeration
What gives and how do I resolve?
给出了什么以及如何解决?
8 个解决方案
#1
42
You can't modify Hashtable while enumerating it. This is what you can do:
枚举时不能修改Hashtable。这是你可以做的:
$myHash = @{}
$myHash["a"] = 1
$myHash["b"] = 2
$myHash["c"] = 3
$myHash = $myHash.keys | foreach{$r=@{}}{$r[$_] = 5}{$r}
Edit 1
编辑1
Is this any simpler for you:
这对你来说更简单:
$myHash = @{}
$myHash["a"] = 1
$myHash["b"] = 2
$myHash["c"] = 3
foreach($key in $($myHash.keys)){
$myHash[$key] = 5
}
#2
11
there is a much simpler way of achieving this. You cannot change the value of a hashtable whilst enumerating it because of the fact that it's a reference type variable. It's exactly the same story in .Net.
有一种更简单的方法来实现这一目标。您可以在枚举时更改哈希表的值,因为它是一个引用类型变量。这与.Net中的故事完全相同。
Use the following syntax to get around it. What we are doing here is converting the keys collection into a basic array using @() notation. We make a copy of the keys collection, and reference that array instead which means we can now edit the hashtable.
使用以下语法来解决它。我们在这里做的是使用@()表示法将密钥集合转换为基本数组。我们制作了密钥集合的副本,并引用该数组,这意味着我们现在可以编辑哈希表。
$myHash = @{}
$myHash["a"] = 1
$myHash["b"] = 2
$myHash["c"] = 3
foreach($key in @($myHash.keys)){
$myHash[$key] = 5
}
#3
4
You do not need to clone the whole hashtable for this example, just enumerating the key collection by forcing it to an array @(...)
is enough:
您不需要为此示例克隆整个哈希表,只需通过将密钥集强制为数组@(...)来枚举密钥集就足够了:
foreach($key in @($myHash.keys)){...
#4
3
Use clone
:
使用克隆:
foreach($key in ($myHash.clone()).keys){ $myHash[$key] = 5 }
or in the one-liner:
或在单行中:
$myHash = ($myHash.clone()).keys | % {} {$myHash[$_] = 5} {$myHash}
#5
2
I'm new to PowerShell, but I'm quite a fan of using in-built functions, because I find it more readable. This is how I would tackle the problem, using GetEnumerator and Clone. This approach also allows one to reference to the existing hash values ($_.value) for modifying purposes.
我是PowerShell的新手,但我非常喜欢使用内置函数,因为我发现它更具可读性。这就是我使用GetEnumerator和Clone解决问题的方法。此方法还允许人们引用现有的哈希值($ _。value)以进行修改。
$myHash = @{}
$myHash["a"] = 1
$myHash["b"] = 2
$myHash["c"] = 3
$myHash.Clone().GetEnumerator() | foreach-object {$myHash.Set_Item($_.key, 5)}
#6
2
You have to get creative!
你必须有创意!
$myHash = @{}
$myHash["a"] = 1
$myHash["b"] = 2
$myHash["c"] = 3
$keys = @()
[array] $keys = $myHash.keys
foreach($key in $keys)
{
$myHash.Set_Item($key, 5)
}
$myHash
Name Value
---- -----
c 5
a 5
b 5
#7
0
Seems when you update the hash table inside the foreach, the enumerator invalidates itself. I got around this by populating a new hash table:
似乎在更新foreach中的哈希表时,枚举器使自身无效。我通过填充新的哈希表来解决这个问题:
$myHash = @{}
$myHash["a"] = 1
$myHash["b"] = 2
$myHash["c"] = 3
$newHash = @{}
foreach($key in $myHash.keys){
$newHash[$key] = 5
}
$myHash = $newHash
#8
0
As mentioned above, clone is the way to go. I had a need to replace any null values in a hash with "Unknown" nd this one-liner does the job.
如上所述,克隆是最佳选择。我需要用“未知”替换散列中的任何空值,并且这个单行完成工作。
($record.Clone()).keys| %{if ($record.$_ -eq $null) {$record.$_ = "Unknown"}}
#1
42
You can't modify Hashtable while enumerating it. This is what you can do:
枚举时不能修改Hashtable。这是你可以做的:
$myHash = @{}
$myHash["a"] = 1
$myHash["b"] = 2
$myHash["c"] = 3
$myHash = $myHash.keys | foreach{$r=@{}}{$r[$_] = 5}{$r}
Edit 1
编辑1
Is this any simpler for you:
这对你来说更简单:
$myHash = @{}
$myHash["a"] = 1
$myHash["b"] = 2
$myHash["c"] = 3
foreach($key in $($myHash.keys)){
$myHash[$key] = 5
}
#2
11
there is a much simpler way of achieving this. You cannot change the value of a hashtable whilst enumerating it because of the fact that it's a reference type variable. It's exactly the same story in .Net.
有一种更简单的方法来实现这一目标。您可以在枚举时更改哈希表的值,因为它是一个引用类型变量。这与.Net中的故事完全相同。
Use the following syntax to get around it. What we are doing here is converting the keys collection into a basic array using @() notation. We make a copy of the keys collection, and reference that array instead which means we can now edit the hashtable.
使用以下语法来解决它。我们在这里做的是使用@()表示法将密钥集合转换为基本数组。我们制作了密钥集合的副本,并引用该数组,这意味着我们现在可以编辑哈希表。
$myHash = @{}
$myHash["a"] = 1
$myHash["b"] = 2
$myHash["c"] = 3
foreach($key in @($myHash.keys)){
$myHash[$key] = 5
}
#3
4
You do not need to clone the whole hashtable for this example, just enumerating the key collection by forcing it to an array @(...)
is enough:
您不需要为此示例克隆整个哈希表,只需通过将密钥集强制为数组@(...)来枚举密钥集就足够了:
foreach($key in @($myHash.keys)){...
#4
3
Use clone
:
使用克隆:
foreach($key in ($myHash.clone()).keys){ $myHash[$key] = 5 }
or in the one-liner:
或在单行中:
$myHash = ($myHash.clone()).keys | % {} {$myHash[$_] = 5} {$myHash}
#5
2
I'm new to PowerShell, but I'm quite a fan of using in-built functions, because I find it more readable. This is how I would tackle the problem, using GetEnumerator and Clone. This approach also allows one to reference to the existing hash values ($_.value) for modifying purposes.
我是PowerShell的新手,但我非常喜欢使用内置函数,因为我发现它更具可读性。这就是我使用GetEnumerator和Clone解决问题的方法。此方法还允许人们引用现有的哈希值($ _。value)以进行修改。
$myHash = @{}
$myHash["a"] = 1
$myHash["b"] = 2
$myHash["c"] = 3
$myHash.Clone().GetEnumerator() | foreach-object {$myHash.Set_Item($_.key, 5)}
#6
2
You have to get creative!
你必须有创意!
$myHash = @{}
$myHash["a"] = 1
$myHash["b"] = 2
$myHash["c"] = 3
$keys = @()
[array] $keys = $myHash.keys
foreach($key in $keys)
{
$myHash.Set_Item($key, 5)
}
$myHash
Name Value
---- -----
c 5
a 5
b 5
#7
0
Seems when you update the hash table inside the foreach, the enumerator invalidates itself. I got around this by populating a new hash table:
似乎在更新foreach中的哈希表时,枚举器使自身无效。我通过填充新的哈希表来解决这个问题:
$myHash = @{}
$myHash["a"] = 1
$myHash["b"] = 2
$myHash["c"] = 3
$newHash = @{}
foreach($key in $myHash.keys){
$newHash[$key] = 5
}
$myHash = $newHash
#8
0
As mentioned above, clone is the way to go. I had a need to replace any null values in a hash with "Unknown" nd this one-liner does the job.
如上所述,克隆是最佳选择。我需要用“未知”替换散列中的任何空值,并且这个单行完成工作。
($record.Clone()).keys| %{if ($record.$_ -eq $null) {$record.$_ = "Unknown"}}