就地转换哈希表值

时间:2015-06-01 19:35:36

标签: string powershell hashtable powershell-v2.0

我有一个哈希表,其值是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

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] }

答案 1 :(得分:1)

我认为没有一种“更有效”的方式来改变价值观。您可以将每个键的值设置为新类型的值($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() }