在 key/value 对拆分 hastable

Split hastable at key/value pair

如何从特定的 key/value 对开始拆分哈希表?

我有如下哈希表,只是更长:

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 但失败了。

我特别想按姓名分开,除了姓名,年龄和职位之外的所有内容都不一致。

我的实际问题是,当 Why = 异端,不幸的是,数据的原始来源是一个字符串列表,这就是我将其转换为哈希表的原因。

哈希表没有排序,因此您不能依赖 "before" 和 "after" 的概念。如果你知道一组完整的键的具体名称,那么你可以遍历哈希表并构建两个新的哈希表,所以如果你想要一个哈希表包含姓名、年龄和职位,而另一个包含其他所有内容,你可以这样做:

$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')

根据评论编辑

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

A [hashtable] 可以(并且经常)用作一种原型对象,它对此非常有用,因为它通常支持相同的语法,并且具有内置的文字支持.

但是您开始 运行 达到它们的极限,在这一点上我认为您想要处理对象数组而不是哈希表数组。

幸运的是,有非常简单的方法可以直接从哈希表在 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})

所以,最后;我想通了,非常感谢@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