在关键/值对中拆分hastable

时间:2017-08-02 20:11:17

标签: powershell hash split hashtable

如何从特定键/值对开始拆分哈希表?

我有以下哈希表,只是更长时间:

Name               Value
----               -----
Name               Alpha
Age                    2
Position           Trick
Start date      01-01-31
End date         Unknown
Name               Corax
Age                   21
Position           Sneak
Earnings          40'000
End Date         Unknown
Name               Horus
Age                   22
Position            Dead
Why               Heresy
End date        03-30-30

我尝试了Group-Object,但失败了。

我特别想把它与名字分开,除名字,年龄和位置之外的一切都不一致。

我的实际问题是,当为什么 = 异端时,我想解析名称年龄的哈希表>,不幸的是,数据的原始来源是字符串列表,这就是我将其转换为哈希表的原因。

2 个答案:

答案 0 :(得分:5)

哈希表没有订购,所以你不能依赖"之前的概念。和"之后"。如果您知道一组完整密钥的特定名称,那么您可以遍历哈希表并构建两个新密钥,因此如果您希望一个哈希表包含名称,年龄和位置,另一个哈希表包含其他所有内容,你可以这样做:

$New1 = @{}
$New2 = @{}

$KeysGroup1 = @('Name','Age','Position') # This could just be one value

$MyHashTable.GetEnumerator().ForEach({
    if ($_.Key -in $KeysGroup1) {
        $New1[$_.Key] = $_.Value
    } else {
        $New2[$_.Key] = $_.Value
    }
})

如果订单对您很重要,您可以使用有序字典。您可以使用快捷方式通过在文字散列表前加上[ordered]类型加速器来创建文字有序字典:

$myOrdered = [ordered]@{ a = 1; z = 5; g = 2 }

从那里你可以做一个类似于上面的方法依赖于订单。

创建一个不基于文字的有序字典:

$myOrdered = New-Object System.Collections.Specialized.OrderedDictionary

# or in PowerShell v5

$myOrdered = [System.Collections.Specialized.OrderedDictionary]::new()

$myOrdered.Add('key','value')

根据评论进行编辑

这听起来更像是数组哈希表,你现在想要过滤这些。

[hashtable]可以(通常)用作一种原型对象,它可能非常有用,因为它通常支持相同的语法,并且内置文字支持。 / p>

但是你开始遇到他们的极限,此时我认为你想要处理一组对象而不是一个哈希表数组。

幸运的是,有很简单的方法可以直接在散列表中创建PowerShell中的对象:

$obj = New-Object -TypeName PSObject -Property $myHash
$obj = [PSCustomObject]$myHash

$objArray = $myHashArray.ForEach({[PSCustomObject]$myHash})

一旦你获得了对象的数组,真正的乐趣就开始了:

$heretics = $objArray.Where({$_.Why -eq 'Heresy'})

您会注意到我甚至无法过滤掉其他属性。你不应该,直到你真的需要。然后,您可以使用Select-Object或只访问您需要的属性。因此,出于显示目的,您可能会这样做:

$heretics | Format-Table Name,Age

您可以使用哈希表创建一个对象,例如添加特殊类型的属性:

$objArray | Add-Member -MemberType ScriptProperty -Name IsHeretic -Value { $this.Why -eq 'Heresy' } -Force

$heretics = $objArray.Where({$_.IsHeretic})

答案 1 :(得分:0)

所以,最后;我想出了什么,非常感谢@briantist指导正确的方向。

我的解决方案代码是:

$startobj =  (0..($hastable.count -1)) | where {$hashtable[$_].keys -like "*Name*"}
$endobj = (0..($hashtable.count -1)) | where {$hashtable[$_].keys -like "*End date*"}
$objindex = (0..($hashtable.count -1))
$numberofobjindex = 0..($hashtable.Where({$_.keys -like "*Name*"}).count - 1)


$hashtableparsed = foreach ($numba in $numberofobjindex) {
  $Conv2data = $hashtable[($startobj[$numba]..$endobj[$numba])] 
    [PSCustomObject] @{
    Name = $Conv2data.Name
    Age = $Conv2data.Age
    Why = $Conv2data.Why

          }
   }  

$hashtableparsed

我意识到我所呈现的散列表数据在每个循环开始时都有一个重复模式Name,最后是End date

所以我基本上对哈希表进行了索引,并标记并索引了循环开始和结束的所有实例。

然后我计算了周期,并且FOR EACH周期捕获了特别是该周期的行中的哈希表数据的数据并将其转换为PSCustomObject