就地转换哈希表值
Convert Hashtable Values In-Place
我有一个哈希表,其值是 int 和字符串(有时是字符串数组)对象的混合。我想将它们全部转换为字符串,但我不知道没有 "rebuilding" 哈希表将每个值转换为字符串的简单方法。有没有更简单、更有效的方法来执行此操作而无需循环遍历值?
这是一个简单的例子。这是我要转换的散列:
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
将它们转换为字符串就足够了:
$($new_test.Keys) | % { $new_test[$key] = [string]$new_test[$key] }
或(如果您不想随意转换所有值):
($new_test.Keys | ? { $new_test[$_] -is [int] }) |
% { $new_test[$key] = [string]$new_test[$key] }
我认为没有 "more efficient" 更改值的方法。您可以将每个键的值设置为新类型的值 ($hash[$key] = $hash[$key].ToString()
),但如果您正在循环,这会很复杂,因为您正在更改被枚举的对象。
您可以通过确保枚举哈希表的键的 copy 来以一种 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() }
我有一个哈希表,其值是 int 和字符串(有时是字符串数组)对象的混合。我想将它们全部转换为字符串,但我不知道没有 "rebuilding" 哈希表将每个值转换为字符串的简单方法。有没有更简单、更有效的方法来执行此操作而无需循环遍历值?
这是一个简单的例子。这是我要转换的散列:
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
将它们转换为字符串就足够了:
$($new_test.Keys) | % { $new_test[$key] = [string]$new_test[$key] }
或(如果您不想随意转换所有值):
($new_test.Keys | ? { $new_test[$_] -is [int] }) |
% { $new_test[$key] = [string]$new_test[$key] }
我认为没有 "more efficient" 更改值的方法。您可以将每个键的值设置为新类型的值 ($hash[$key] = $hash[$key].ToString()
),但如果您正在循环,这会很复杂,因为您正在更改被枚举的对象。
您可以通过确保枚举哈希表的键的 copy 来以一种 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() }