无法从哈希表

时间:2016-11-30 16:16:01

标签: powershell hashtable

在Powershell中,我有一个哈希表,其中包含与此类似的数据 -

Name                   Value                                           
----                   -----                                           
1-update.bat           1                                               
2-update.bat           2                                               
3-update.bat           3                                               
3.1-update.bat         3.1                                             
4-update.bat           4    

我还有一个包含数字的变量,例如3

我想要做的是遍历数组并删除值小于或等于3的任何条目

我认为这很容易,尤其是the docs表示表格中包含.remove方法。但是,我在下面的代码失败了,这就是错误 -

  

异常调用"删除"用" 1"参数:"收集是一个   固定大小。"

以下是我使用的代码 -

$versions = @{}
$updateFiles | ForEach-Object {
    $versions.Add($_.name, [decimal]($_.name -split '-')[0])
}

[decimal]$lastUpdate = Get-Content $directory\$updatesFile

$versions | ForEach-Object {
    if ( $_.Value -le $lastUpdate ) {
        $versions.Remove($version.Name)
    }
}

我首先尝试以不同的方式循环$versions,同时尝试foreachfor方法,但两者都以同样的方式失败。

我还尝试创建一个临时数组来保存要删除的版本的名称,然后循环该数组以删除它们,但这也失败了。

接下来我点击谷歌,虽然我可以找到几个类似的问题,但没有一个能回答我的具体问题。大多数情况下,他们建议使用一个列表(New-Object System.Collections.Generic.List[System.Object]),我可以告诉我这里没有任何帮助。

是否有人能够提出修复建议?

4 个答案:

答案 0 :(得分:5)

在这里,您可以使用.Remove(),您只需要哈希表的克隆,以便它可以让您在枚举时删除项目。

[hashtable]$ht = @{ '1-update.bat'=1;'2-update.bat'=2;'3-update.bat'=3;'3.1-update.bat'=3.1; '4-update.bat'=4    }

#Clone so that we can remove items as we're enumerating
$ht2 = $ht.Clone()
foreach($k in $ht.GetEnumerator()){ 
    if([decimal]$k.Value -le 3){
        #notice, deleting from clone, then return clone at the end
        $ht2.Remove($k.Key) 
    } 
}


$ht2

请注意,我也投了原始变量,因此它可能不需要显式哈希表,但我喜欢这样做,至少要保持清晰。

答案 1 :(得分:0)

看起来您只是将ForEach-Objectforeach混淆了但只有一半(可能之前是foreach并且您将其转换了。)

您无法直接向[hashtable]发送ForEach-Object;在这种情况下,$_只会引用您发送的单个[hashtable]。您可以这样做:

foreach ($version in $versions.GetEnumerator()) {
    $version.Name
    $version.Value
}

或者您可以这样做:

$versions.Keys | ForEach-Object {
    $_  # the name/key
    $versions[$_]  # the value
    $versions.$_   # also the value
}

答案 2 :(得分:0)

$ht.Keys  # list all keys
$ht[$_] # take an element of hastable
$ht.Remove($_)  # remove an element of hastable by his key

你想要什么:

$ht.Keys | ? { $ht[$_] -le 3 } | %{$ht.Remove($_) }

答案 3 :(得分:0)

您需要创建一个临时数组来保存要删除的版本的名称/关键字,然后循环该数组以将其从哈希表中删除:

$versionKeysToRemove = $versions.Keys | Where-Object { $versions[$_] -le $lastUpdate }
$versionKeysToRemove | ForEach-Object { $versions.Remove($_) }

或更短:

($versions.Keys | ? { $versions[$_] -le $lastUpdate }) | % { $versions.Remove($_) }

请注意括号。