【问题标题】:Sort a nested hash table by value按值对嵌套哈希表进行排序
【发布时间】:2020-03-14 21:08:17
【问题描述】:

我有一个这样的哈希数组:

$weeklyStats[$RecipientName][$weekNr][$total]

这是在循环中创建的:

$weeklyStats = @{}
$weekNr = get-date -UFormat %V

ForEach ($RecipientName in $MailTraffic.keys)  
{  

    $weeklyStats[$RecipientName] = @{}
    $weeklyStats[$RecipientName][$weekNr] = @{}
    $weeklyStats[$RecipientName][$weekNr]['Total'] = 0
    $weeklyStats[$RecipientName][$weekNr]['Sent'] = 0
    $weeklyStats[$RecipientName][$weekNr]['Received'] = 0

    foreach($item in $MailTraffic[$RecipientName].keys)  
    {  
        weeklyStats[$RecipientName][$weekNr]['Total'] =+ 1
        if $MailTraffic[$RecipientName]['transaction'] == "Sent"
        {
            $weeklyStats[$RecipientName][$weekNr]['Sent'] =+ 1
        }
        else
        {
            $weeklyStats[$RecipientName][$weekNr]['Received'] =+ 1
        }
    }
}

我不知道如何在 Powershell 中“转储”一个变量,但这里是 json 中的内容:

{
    "mike":  {
                           "11":  {
                                      "Total":   411,
                                      "Sent":     21,
                                      "Received":390,
                                  }
              },
    "peter":  {
                           "11":  {
                                      "Total":   751,
                                      "Sent":     51,
                                      "Received":700,
                                  }
              },
    "frank":  {
                           "11":  {
                                      "Total":   620,
                                      "Sent":     20,
                                      "Received":600,
                                  }
              },
}

我想按 $total 的降序打印键和值。 如果哈希表只有一层深,我只能找到如何做到这一点的示例。

预期的输出是:

Name        Total       Received    Sent
-----       -----       -----       -----
peter       751         700         51
frank       620         600         20
mike        411         390         21      

【问题讨论】:

  • $stats$name$total 在这里包含什么?
  • 这包含在我的问题中吗? $stats 是哈希表的名称,$name 是字符串,weeknr 和 total 是整数。
  • 我宁愿从控制台看到$stats 的输出。
  • 为了得到你的输出,我设想$stats 被创建为$stats = @{'Frank' = @{10 = @{ 500 = 'Frank , 10, 500'}}},@{'Mike' = @{10 = @{ 673 = 'Mike , 10, 673}}}。我敢打赌,那是不正确的。所以我想看看它是如何真正创建的。
  • 为了让您从$stats[$name][$weekNr][$total] 输出Frank , 10, 500,您必须有一个静态设置所有值的字符串,因为您的两个示例与间距不一致,因此它是插值输出。

标签: powershell


【解决方案1】:

通过引用内部哈希表的Keys 属性进行排序,然后分配给新的[ordered] 字典:

$sorted = [ordered]@{}

$stats.GetEnumerator() |Sort-Object {
  # Sort by first key from each inner hashtable
  $_.Value.Keys |Select -First 1
} -Descending |ForEach-Object {
  # re-assign to our ordered dictionary
  $sorted[$_.Key] = $_.Value
}

$sorted 现在包含您的新排序字典

【讨论】:

  • Tnx,不幸的是我的例子是错误的:|当添加额外级别时,我仍然无法应用您的示例。
  • @Lunacy 您能否更新您的问题以说明您是如何创建此嵌套哈希表的?
【解决方案2】:

大多数 PowerShell cmdlet 旨在处理(流!)[PSObject] 类型(包括 [PScustomerObject] 类型)输入和输出列表。
(了解差异参见例如Difference between PSObject, Hashtable, and PSCustomObject)
嵌套哈希表很难在 PowerShell 中维护和处理(另请参阅:Powershell Multidimensional Arrays),因为 PowerShell 针对流式处理进行了优化,这对于级联对象来说相当困难,因此我建议您将嵌套哈希表转换为(相当扁平)[PScustomerObject]列表,类似于:

$PSStats =
    ForEach ($name in $Stats.Keys) {
        ForEach ($weekNr in $_.Keys) {
            ForEach ($total in $_.Keys) {
                [pscustomobject]@{name = $name; weekNr = $weekNr; total = $total}
            }
        }
    }

将其转换为PSCustomObject 列表后,您可以轻松对其进行排序显示结果:

$PSStats | Sort-Object Total

【讨论】:

  • 嗯,我是个白痴,因为涉及到一些私人数据,所以我简化了示例,不幸的是,这不具有代表性,而且平面列表也行不通。我现在更正了。
【解决方案3】:

我会从您的哈希表中创建一个自定义对象,然后对 Title 属性进行排序:

# Creation of $mailtraffic
$mailtraffic = @{'Mike' = @{'Total' = 411; 'Sent' = 21; 'Received' = 390};'Peter' = @{'Total' = 751; 'Sent' = 51; 'Received' = 700};'Frank' = @{'Total' = 620; 'Sent' = 20; 'Received' = 600}}

# Sorting Code
$mailtraffic.GetEnumerator() |
    Select @{n='Name';e={$_.Key}},@{n='Total';e={$_.Value.Total}},@{n='Received';e={$_.Value.Received}},@{n='Sent';e={$_.Value.Sent}} |
        Sort Total -Descending

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多