Сортировать вложенную таблицу ha sh по значению - PullRequest
2 голосов
/ 15 марта 2020

У меня есть массив ha sh как таковой:

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

, который создан в al oop как таковой:

$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
        }
    }
}

I не знаю, как «сбросить» переменную в 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,
                                  }
              },
}

Я хочу распечатать ключи и значения в порядке убывания общей суммы $. Я могу только найти примеры, как это сделать, если таблица ha sh имеет только один уровень глубины.

Предполагаемый результат будет:

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

Ответы [ 3 ]

0 голосов
/ 15 марта 2020

Большинство командлетов PowerShell предназначены для обработки (поток!) [PSObject] типа (который включает в себя [PScustomerObject]) списки для ввода и вывода.
(Чтобы понять разницу см., например, Разница между PSObject, Hashtable и PSCustomObject ) .
Вложенные таблицы ha sh трудно поддерживать и обрабатывать в PowerShell (см. также: Многомерные массивы Powershell ) поскольку 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
0 голосов
/ 15 марта 2020

Я бы просто создал пользовательский объект из ваших таблиц ha sh, а затем отсортировал по свойству 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
0 голосов
/ 15 марта 2020

Сортировка по ссылке на свойство 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 теперь содержит новый отсортированный словарь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...