问题 将哈希表转换为字符串数组


如何将哈希表转换为字符串数组? 假设$ l_table是一个哈希表。如果我试试

$l_array = $l_table | format-table

然后$ l_array是一个数组,但是是一个“FormatEntryData”对象的数组。 如果我做

[string[]]$l_array = $l_table | format-table

然后$ l_array是一个字符串数组,但字符串都是“Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData”。如果我试试

$l_array = $l_table | out-string

那么$ l_array就是一个字符串。我已经尝试了很多其他的东西,但没有任何作用,没有手动循环,我真的不想做。


7024
2018-01-28 18:11


起源



答案:


大卫I.麦金托什自己的答案 效果很好,但应该注意结果数组的元素对应 所有 默认输出的行,包括:

  • 空的前导和尾随线
  • 两个标题行(具有列名称和分隔线的行)

Out-String 只需将您在控制台(终端)中通常看到的内容发送到字符串,默认情况下为  字符串,并与 -Stream 作为一个 排列 字符串。

这是David的命令的变体,它删除了标题和空行:

[string[]] $l_array = ($l_table | out-string -stream) -notmatch '^$' | select -Skip 2

这个答案的其余部分表明了 如何 控制 获得的字符串表示;它使用PS v3 +语法简洁。

注意:为清楚起见,将调用示例输入哈希表 $ht (不 $l_table)在以下示例中。

  • 得到所有 按键 作为字符串数组:

    $ht.Keys | % ToString
    
  • 得到所有  作为字符串数组:

    $ht.Values | % ToString
    
  • 获取自定义表示 键值对,格式 <key>=<value>;注意 .GetEnumerator() 需要发送键值对 个别地 通过管道;默认情况下,PowerShell会传递哈希表 作为一个整体

    $ht.GetEnumerator()  | % { "$($_.Name)=$($_.Value)" }
    

请注意,虽然 .ToString(),这也适用 隐式 在插值过程中,适用于 内建的 .NET类型,其他类型将只是一般打印 类型名称,除非他们 .ToString() 重写方法以返回更有意义的自定义表示(幸运的是,PowerShell cmdlet返回的类型通常是这种情况)。

选择值的属性以在字符串中表示它的一个简单示例:

# Sample hashtable containing a value of a non-built-in type,
# [System.Diagnostics.Process]    
$ht = @{ one = 1; two = $(Get-Process -ID $PID) }

# Use the `.Path` property to represent the value.
$ht.GetEnumerator()  | % { "$($_.Name)=$($_.Value.Path)" }

10
2018-03-20 20:18



是的,你是对的。在我原来的问题中,我还不够清楚:事实上,我想要的是通常在控制台上看到的输出。你的榜样 $ht.GetEnumerator() | % { "$($_.Name)=$($_.Value)" } 是正确的,但不是我想要的。循环或管道只是获得一个手动构造的字符串列表是相当简单的。诀窍是通过使用powershell的内部函数而不是手动构造字符串来使字符串与powershell输出到控制台的字符串相同。 - David I. McIntosh
@ DavidI.McIntosh:明白了;我只是认为我会补充你的答案,因为问题的标题是通用的,可能会吸引读者寻找解决你的具体问题的变化。 - mklement0
是的。你的答案很好,提供了获得你想要的任何东西的一般框架。 - David I. McIntosh


答案:


大卫I.麦金托什自己的答案 效果很好,但应该注意结果数组的元素对应 所有 默认输出的行,包括:

  • 空的前导和尾随线
  • 两个标题行(具有列名称和分隔线的行)

Out-String 只需将您在控制台(终端)中通常看到的内容发送到字符串,默认情况下为  字符串,并与 -Stream 作为一个 排列 字符串。

这是David的命令的变体,它删除了标题和空行:

[string[]] $l_array = ($l_table | out-string -stream) -notmatch '^$' | select -Skip 2

这个答案的其余部分表明了 如何 控制 获得的字符串表示;它使用PS v3 +语法简洁。

注意:为清楚起见,将调用示例输入哈希表 $ht (不 $l_table)在以下示例中。

  • 得到所有 按键 作为字符串数组:

    $ht.Keys | % ToString
    
  • 得到所有  作为字符串数组:

    $ht.Values | % ToString
    
  • 获取自定义表示 键值对,格式 <key>=<value>;注意 .GetEnumerator() 需要发送键值对 个别地 通过管道;默认情况下,PowerShell会传递哈希表 作为一个整体

    $ht.GetEnumerator()  | % { "$($_.Name)=$($_.Value)" }
    

请注意,虽然 .ToString(),这也适用 隐式 在插值过程中,适用于 内建的 .NET类型,其他类型将只是一般打印 类型名称,除非他们 .ToString() 重写方法以返回更有意义的自定义表示(幸运的是,PowerShell cmdlet返回的类型通常是这种情况)。

选择值的属性以在字符串中表示它的一个简单示例:

# Sample hashtable containing a value of a non-built-in type,
# [System.Diagnostics.Process]    
$ht = @{ one = 1; two = $(Get-Process -ID $PID) }

# Use the `.Path` property to represent the value.
$ht.GetEnumerator()  | % { "$($_.Name)=$($_.Value.Path)" }

10
2018-03-20 20:18



是的,你是对的。在我原来的问题中,我还不够清楚:事实上,我想要的是通常在控制台上看到的输出。你的榜样 $ht.GetEnumerator() | % { "$($_.Name)=$($_.Value)" } 是正确的,但不是我想要的。循环或管道只是获得一个手动构造的字符串列表是相当简单的。诀窍是通过使用powershell的内部函数而不是手动构造字符串来使字符串与powershell输出到控制台的字符串相同。 - David I. McIntosh
@ DavidI.McIntosh:明白了;我只是认为我会补充你的答案,因为问题的标题是通用的,可能会吸引读者寻找解决你的具体问题的变化。 - mklement0
是的。你的答案很好,提供了获得你想要的任何东西的一般框架。 - David I. McIntosh


[string[]]$l_array = $l_table | out-string -stream

4
2018-01-28 18:25





哈希只是一个哈希表,所以它有一个键和一个值属性。

$hash = @{}

$hash["foo"] = "bob"

$hash.Values

$hash.Values | Out-string

如果你想获得枚举器,它将返回keyvaluepair

$hash.GetEnumerator() |%{$_ | out-string}

2
2018-01-28 18:15



这只获取值。 - David I. McIntosh
我更新了答案,你可以再提几个细节,我不确定你要找的结果是什么。 - rerun


这是一个常见问题;必须通过键或值检索Hashtable,但是你无法获得对的集合 - 毕竟这是原始哈希表。在我的例子中,哈希表由“字典”表示(你会记得来自VBS :-)。但是,您需要确定一个分隔符来分隔键和值,在本例中为“Key < - > Value”

$ARRAY = ( $DICT.Keys | foreach-object { "$_<->$($DICT[$_])"})

如果需要,您甚至可以先对键进行排序。在这种情况下,我将其反转为Value <---> Key并按值排序。我还将字符串扩展了一点,以使其更加冗长但清晰易读:

$ARRAY = ( $DICT.Keys | foreach-object { $DICT[$_] + "<--->" + $_} | sort-object)

0
2018-03-03 16:55