【问题标题】:PSCustomObject to HashtablePSCustomObject 到哈希表
【发布时间】:2011-04-13 23:57:41
【问题描述】:

PSCustomObject 转换为Hashtable 的最简单方法是什么?它的显示就像一个带有 splat 运算符、花括号和似乎是键值对的东西。当我尝试将其转换为 [Hashtable] 时,它不起作用。我也试过.toString(),分配的变量说它是一个字符串,但什么也没显示——有什么想法吗?

【问题讨论】:

标签: powershell hashtable pscustomobject


【解决方案1】:

不应该太难。像这样的东西应该可以解决问题:

# Create a PSCustomObject (ironically using a hashtable)
$ht1 = @{ A = 'a'; B = 'b'; DateTime = Get-Date }
$theObject = new-object psobject -Property $ht1

# Convert the PSCustomObject back to a hashtable
$ht2 = @{}
$theObject.psobject.properties | Foreach { $ht2[$_.Name] = $_.Value }

【讨论】:

  • 请注意$_.Name 已经是一个字符串,所以$ht2[$_.Name]$h.($_.Name) 将与"$($_.Name)" 一样有效。
  • 请注意,这不适用于ConvertFrom-Json 创建的 PSCustomObjects。 This question 解决了这个问题。
  • @BenV:澄清一下:问题源于 嵌套 自定义对象,而不是使用 ConvertFrom-Json 本身,它也会产生 [PSCustomObject] 实例。换句话说:生成非嵌套对象的 JSON 源工作得很好;例如:('{ "foo": "bar" }' | ConvertFrom-Json).psobject.properties | % { $ht = @{} } { $ht[$_.Name] = $_.Value } { $ht }
  • 请参阅下面来自@Svyatoslav Pidgorny 的答案,该答案正在使用 PowerShell 6 或 7 中的新功能以获得更简单的方法! stackoverflow.com/a/61742479/3425553
【解决方案2】:

Keith 已经给你答案了,这只是用单线做同样的另一种方式:

$psobject.psobject.properties | foreach -begin {$h=@{}} -process {$h."$($_.Name)" = $_.Value} -end {$h}

【讨论】:

  • 嘿,从非常相似的东西开始,只是它的长度足以调用 SO 水平滚动条。顺便说一句,我认为您的 $'s 缺少一些 _'s。 :-)
  • 这就是我试图避免的,最终它吞下了下划线符号。谢谢!
  • @ShayLevy:把所有东西放在同一条线上有什么好处?
  • 不错;如果您使用% 和位置参数作为块,您可以缩短为$psobject.psobject.properties | % { $ht = @{} } { $ht[$_.Name] = $_.Value } { $ht }。 @Rubanov:它不必在单个 line 上,但优点是单个 statement(管道)创建哈希表。
【解决方案3】:

这适用于由 ConvertFrom_Json 创建的 PSCustomObjects。

Function ConvertConvertFrom-JsonPSCustomObjectToHash($obj)
{
    $hash = @{}
     $obj | Get-Member -MemberType Properties | SELECT -exp "Name" | % {
                $hash[$_] = ($obj | SELECT -exp $_)
      }
      $hash
}

免责声明:我几乎不了解 PowerShell,所以这可能不如它应该的那么干净。但它有效(仅适用于一个级别)。

【讨论】:

  • 更简洁一些(可能更难理解)$hash=@{};$obj | Get-Member -MemberType Properties | foreach { $hash.Add($_.Name,$obj.($_.Name))}
【解决方案4】:

这是一个也适用于嵌套哈希表/数组的版本(如果您尝试使用 DSC ConfigurationData 执行此操作,这很有用):

function ConvertPSObjectToHashtable
{
    param (
        [Parameter(ValueFromPipeline)]
        $InputObject
    )

    process
    {
        if ($null -eq $InputObject) { return $null }

        if ($InputObject -is [System.Collections.IEnumerable] -and $InputObject -isnot [string])
        {
            $collection = @(
                foreach ($object in $InputObject) { ConvertPSObjectToHashtable $object }
            )

            Write-Output -NoEnumerate $collection
        }
        elseif ($InputObject -is [psobject])
        {
            $hash = @{}

            foreach ($property in $InputObject.PSObject.Properties)
            {
                $hash[$property.Name] = ConvertPSObjectToHashtable $property.Value
            }

            $hash
        }
        else
        {
            $InputObject
        }
    }
}

【讨论】:

  • 这是唯一适用于我的具有多级嵌套对象和数组的数据的版本。
  • 多级嵌套对象的优秀和优雅的解决方案。
  • 如上一个答案的评论中所述,上面的代码处理复杂/嵌套的哈希表,非常适合处理来自ConvertFrom-Json 的内容。另见this question
  • 我无法让嵌套对象“按原样”工作:@{ Name = "test1"; nested = @{ license = 'x'; cert = 'y' } } | Convert-PSObjectToHashTable 相反,我必须在第 15 行添加 GetEnumerator()foreach ($object in $InputObject.GetEnumerator()) { ConvertPSObjectToHashtable $object }
  • Adam Bertram 的相同代码可以在这里找到:4sysops.com/archives/convert-json-to-a-powershell-hash-table
【解决方案5】:

我的代码:

function PSCustomObjectConvertToHashtable() {
    param(
        [Parameter(ValueFromPipeline)]
        $object
    )

    if ( $object -eq $null ) { return $null }

    if ( $object -is [psobject] ) {
        $result = @{}
        $items = $object | Get-Member -MemberType NoteProperty
        foreach( $item in $items ) {
            $key = $item.Name
            $value = PSCustomObjectConvertToHashtable -object $object.$key
            $result.Add($key, $value)
        }
        return $result
    } elseif ($object -is [array]) {
        $result = [object[]]::new($object.Count)
        for ($i = 0; $i -lt $object.Count; $i++) {
            $result[$i] = (PSCustomObjectConvertToHashtable -object $object[$i])
        }
        return ,$result
    } else {
        return $object
    }
}

【讨论】:

    【解决方案6】:

    PowerShell 6 中的一项新功能启用了我非常懒惰的方法:

    $myhashtable = $mypscustomobject | ConvertTo-Json | ConvertFrom-Json -AsHashTable
    

    【讨论】:

    • 我喜欢这个!
    • 我希望避免使用它,因为往返文本并返回对象格式似乎有点荒谬......但我可以确认它不起作用,而且它是最方便(如果不是高性能)的语法。
    • @jrypkahauer:我猜你的意思是“它确实有效”?
    • 这是一个安全的假设 ?
    • @minusone - 我确实做到了。谢谢,已更正。 :) 大声笑可怕的错字!
    猜你喜欢
    • 2021-04-04
    • 1970-01-01
    • 2016-08-03
    • 2023-03-31
    • 2011-10-27
    • 1970-01-01
    • 2023-03-27
    相关资源
    最近更新 更多