【问题标题】:Convert Hashtable Values In-Place就地转换哈希表值
【发布时间】:2015-08-15 09:39:27
【问题描述】:

我有一个哈希表,其值是 int 和 string(有时是字符串数组)对象的混合。我想将它们全部转换为字符串,但如果不“重建”哈希表,将每个值转换为字符串,我不知道一种简单的方法。有没有更简单、更有效的方法来做到这一点而无需遍历值?

这是一个简单的例子。这是我要转换的哈希:

PS C:\Users\me> $test | Select -ExpandProperty Values | % { $_.GetType() }

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object
True     True     String                                   System.Object
True     True     String                                   System.Object
True     True     Int32                                    System.ValueType
True     True     Int32                                    System.ValueType
True     True     Int32                                    System.ValueType

到这里:

PS C:\Users\gross> $new_test | Select -ExpandProperty Values | % { $_.GetType() }

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object
True     True     String                                   System.Object
True     True     String                                   System.Object
True     True     String                                   System.Object
True     True     String                                   System.Object
True     True     String                                   System.Object

【问题讨论】:

    标签: string powershell hashtable powershell-2.0


    【解决方案1】:

    将它们转换为字符串就足够了:

    $($new_test.Keys) | % { $new_test[$key] = [string]$new_test[$key] }
    

    或者(如果您不想随意转换所有值):

    ($new_test.Keys | ? { $new_test[$_] -is [int] }) |
      % { $new_test[$key] = [string]$new_test[$key] }
    

    【讨论】:

    • 我尝试了类似的方法并得到了An error occurred while enumerating through a collection: Collection was modified; enumeration operation may not execute.,因此我的回答。我错过了什么吗?
    • 您需要扩展子表达式中的键以将其与更改哈希表分离。
    • 啊,明白了。我最终以迂回的方式创建了一个新数组。子表达式更简洁。
    【解决方案2】:

    我认为没有“更有效”的方式来更改值。您可以将每个键的值设置为新类型的值 ($hash[$key] = $hash[$key].ToString()),但如果您正在循环,这会很复杂,因为您正在更改被枚举的对象。

    您可以通过确保枚举散列表键的副本,然后用它修改散列来以一种hacky方式解决此问题:

    $hash = @{
        a = '1'
        b = 2
        c = 3
        d = '4'
        e = 5
    }
    
    Write-Host "`nBefore:`n"
    
    $hash.Values | ForEach-Object { $_.GetType() }
    
    $keys = [Array]::CreateInstance([String], $hash.Keys.Count)
    $hash.Keys.CopyTo($keys, 0) | Out-Null
    
    
    $keys | ForEach-Object {
        $hash[$_] = $hash[$_].ToString()
    }
    
    Write-Host "`nAfter:`n"
    
    $hash.Values | ForEach-Object { $_.GetType() }
    

    但老实说,我认为只做一个新的更容易:

    $hash = @{
        a = '1'
        b = 2
        c = 3
        d = '4'
        e = 5
    }
    
    Write-Host "`nBefore (`$hash):`n"
    
    $hash.Values | ForEach-Object { $_.GetType() }
    
    $newhash = @{}
    $hash.Keys | ForEach-Object { $newhash[$_] = $hash[$_].ToString() }
    
    Write-Host "`nAfter (`$newhash):`n"
    
    $newhash.Values | ForEach-Object { $_.GetType() }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-27
      • 2019-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-08
      • 2012-04-26
      • 1970-01-01
      相关资源
      最近更新 更多