如何从Powershell v3中的哈希数组生成PSCustomObjects数组?
假设我在Powershell v3中有一个哈希数组:如何从Powershell v3中的哈希数组生成PSCustomObjects数组?,powershell,powershell-3.0,Powershell,Powershell 3.0,假设我在Powershell v3中有一个哈希数组: > $hashes = 1..5 | foreach { @{Name="Item $_"; Value=$_}} 我可以将单个哈希转换为PSCustomObject,如下所示: > $co = [PSCustomObject] $hashes[0] > $co | ft -AutoSize Value Name ----- ---- 1 Item 1 > $co.GetType() IsPub
> $hashes = 1..5 | foreach { @{Name="Item $_"; Value=$_}}
我可以将单个哈希转换为PSCustomObject
,如下所示:
> $co = [PSCustomObject] $hashes[0]
> $co | ft -AutoSize
Value Name
----- ----
1 Item 1
> $co.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False PSCustomObject System.Object
到目前为止,一切顺利。当我尝试在管道中将整个哈希数组转换为PSCustomObjects
时,就会出现问题:
> ($hashes | foreach { [PSCustomObject] $_})[0].getType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Hashtable System.Object
如您所见,我得到的是一个Hashtable
对象数组,而不是PSCustomObjects
。为什么我会有不同的行为,我怎样才能实现我想要的
谢谢。请尝试直接调用
新对象,而不是强制转换:
# > ($hashes | foreach { New-Object -TypeName PSCustomObject -Property $_})[0].getType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False PSCustomObject System.Object
而且,奇怪的是,这似乎起了作用:
# > (0..4 | foreach { ([PSCustomObject]$hashes[$_])})[0].GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False PSCustomObject System.Object
$hashes = 1..5 | foreach { @{Name="Item $_"; Value=$_}}
foreach ($hash in $hashes)
{([PSCustomObject]$hash).gettype()}
为什么??我不知道,使用流水线哈希表条目执行强制转换似乎有问题。这似乎有效:
# > (0..4 | foreach { ([PSCustomObject]$hashes[$_])})[0].GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False PSCustomObject System.Object
$hashes = 1..5 | foreach { @{Name="Item $_"; Value=$_}}
foreach ($hash in $hashes)
{([PSCustomObject]$hash).gettype()}
我还没有弄清楚确切的原因(每个人都在学习一些东西),但您的问题与$\uu
管道元素有关。如果我强制转换$\uuu
$hashes = 1..5 | foreach { @{Name="Item $_"; Value=$_}}
$hashes | %{([pscustomobject][hashtable]$_)}
输出
Value Name
----- ----
1 Item 1
2 Item 2
3 Item 3
4 Item 4
5 Item 5
奇怪的东西
当我在测试时,我不喜欢Name
和Value
(这就是文本哈希表对标题的作用,我在测试时发现它令人困惑),所以我将后者改为Data
,然后输出就不同了。我只是出于好奇才发布它。很难在帖子中显示结果
Name Data
---- ----
Item 1 1
Item 2 2
Item 3 3
Item 4 4
Item 5 5
管道变量$\uuz
的值似乎被包装到PSObject
中,并被转换为PSCustomObject
> $hashes=@{Value=1},[PSObject]@{Value=2}
> $hashes[0].GetType().FullName
System.Collections.Hashtable
> $hashes[1].GetType().FullName
System.Collections.Hashtable
# It seems that both $hashes elements are Hashtable,
> [Type]::GetTypeArray($hashes).FullName
System.Collections.Hashtable
System.Management.Automation.PSObject
# But, as you can see, second one is not.
> ([PSCustomObject]$hashes[0]).GetType().FullName
System.Management.Automation.PSCustomObject
> ([PSCustomObject]$hashes[1]).GetType().FullName
System.Collections.Hashtable
# And that difference break cast to PSCustomObject.
第二种方法类似于ops问题中的发现,他调用了$hashes[0]
新的对象解决方案。马特的[哈希表]演员也是如此。奇怪。是的,[hashtable]演员扮演了这个角色。我很想知道为什么需要这样做。我从文档中找到了这一点,它可能提供了一个线索:PSCustomObject类型的基本对象告诉Windows PowerShell运行时,封装的PSObject对象没有有意义的基本对象。但是,这种封装PSObject对象的类型确实提供了一个类型名属性包,cmdlet开发人员可以将扩展成员添加到该属性包中。开发人员还可以指定对象的类型名称,这允许此对象与具有相同类型名称的其他PSObject对象共享其扩展成员。当我设置Data=“$”时,会得到不同的结果。它显示的字符串似乎与int不同。您总是在周围进行转换和键入问题:)在这种情况下,您使用的是foreach语言构造。在管道中,“foreach”被视为foreach对象命令的别名。请参阅关于Foreach帮助主题。@David-我知道这是一个Foreach循环。我不知道它必须是一个管道解决方案,或者考虑到哈希表集合已经驻留在内存中,这样做有什么特别的好处。