首页 > 解决方案 > Powershell 哈希:添加/更新值是否容易?

问题描述

在 Powershell 中,您可以使用 .Add 将新的键/值对插入到现有哈希中。如果哈希已经包含密钥,则会导致错误。对于已知键,所需的(由我 :) 行为将是,只需将现有值更新为提供的值。我可以用很多墨水来做到这一点。将 .Add 命令放在 try 短语中,并在 catch 中更改值 - 效果很好,但需要消耗墨水!

说真的,因为我在解析多个配置时到处都有这种逻辑(这是已经设置并需要更新还是新设置?),这会导致代码混乱:

# $msHashtable is potentially empty at this point or may not contain the key 
try {
    $myHashtable.Add($thisKey, $thisValue)
} 
catch {
    $myHashtable.$thisKey = $thisValue
}

我拥有的另一个哈希问题是:

如果需要,我可以提供代码,但我希望问题足够清楚。由于在我的现实世界示例中,除了相关部分之外还有很多其他代码,所以我现在不会发布它......

最好的,

旧辛纳克

标签: powershellnestedhashtable

解决方案


对于问题的第一部分,您已经得到了有用的答案。

这是我在第二部分的尝试——如何分配嵌套哈希表的成员。在创建任何尚不存在的父哈希表时,没有简单的内置语法来设置嵌套值,因此我Set-TreeValue为此创建了一个可重用的函数。

function Set-TreeValue( $ht, [String] $path, $value ) {

    # To detect errors like trying to set child of value-type leafs.
    Set-StrictMode -Version 3.0  

    do {
        # Split into root key and path remainder (", 2" -> split into max. 2 parts)
        $key, $path = $path -split '\.', 2

        if( $path ) {
            # We have multiple path components, so we may have to create nested hash table.
            if( -not $ht.Contains( $key ) ) {
                $ht[ $key ] = [ordered] @{}
            }
            # Enter sub tree. 
            $ht = $ht[ $key ]
        }
        else {
            # We have arrived at the leaf -> set its value
            $ht[ $key ] = $value
        }
    }
    while( $path )
}

演示:

$ht = [ordered] @{}

Set-TreeValue $ht foo.bar.baz 42   # Create new value and any non-existing parents
Set-TreeValue $ht foo.bar.baz 8    # Update existing value
Set-TreeValue $ht foo.bar.bam 23   # Add another leaf
Set-TreeValue $ht fop 4            # Set a leaf at root level
#Set-TreeValue $ht fop.zop 16      # Outputs an error, because .fop is a leaf
Set-TreeValue $ht 'foo bar' 15     # Use a path that contains spaces

$ht | ConvertTo-Json               # Output the content of the hash table

输出:

{
  "foo": {
    "bar": {
      "baz": 8,
      "bam": 23
    }
  },
  "fop": 4,
  "foo bar": 15
}

注意:我选择创建嵌套哈希表,OrderedDictionary因为它们比常规哈希表更有用(例如,确保 JSON 输出中的顺序)。[ordered]如果您想要无序哈希表(可能具有轻微的性能优势),请删除。


推荐阅读