Как объединить две хеш-таблицы Powershell с вложенными таблицами и массивами - PullRequest
0 голосов
/ 30 ноября 2018

Нужно объединить две хеш-таблицы с вложенными таблицами и / или массивами.Я нашел сообщение Слияние хеш-таблиц в Powershell: как? , что привело меня к созданию следующей функции, модифицирующей код sonjz, найденный в посте, и он хорошо работает с не вложенными объектами, однако, когда дело доходит до вложенных таблиц и массивов вродительские таблицы не могут быть правильно объединены.

как можно обновить этот код для вывода слияния хеш-таблиц с вложенными таблицами и / или массивами, если они существуют?

    Function Merge-HashTables
    {
        [CmdletBinding(ConfirmImpact = 'Low',
                       PositionalBinding = $true)]
        [OutputType([hashtable])]
        param
        (
            [Parameter(Mandatory = $true,
                       Position = 0)]
            [ValidateNotNullOrEmpty()]
            [hashtable]$BaseTable,

            [Parameter(Mandatory = $true,
                       Position = 1)]
            [ValidateNotNullOrEmpty()]
            [hashtable]$NewTable
        )

        Begin
        {
            [hashtable]$Base = $BaseTable.Clone()
        }

        Process
        {
            foreach ($Key in $NewTable.Keys)
            {
                if ($Base.ContainsKey($Key))
                {
                    $Base.Remove($Key)
                }
            }

            Write-Output ($Base + $NewTable)
        }
    }

1 Ответ

0 голосов
/ 30 ноября 2018

Когда в слиянии возникает конфликт ключей, сейчас вы просто отбрасываете один и оставляете другой, поэтому, если это фактически два разных объекта, вы всегда потеряете некоторую информацию.В случае, если сами объекты являются хеш-таблицами или массивами, это, конечно, остается верным, поэтому для того, чтобы справиться с этим, вам нужно решить, какие типы вы хотите обрабатывать специальной логикой слияния.

В случае хеш-таблиц вы можете рекурсивно вызывать свою собственную функцию.Вам понадобится параметр уровня, чтобы ограничить, насколько далеко вы можете набирать и / или обрабатывать циклические ссылки.

Для массивов вы можете просто сложить их вместе.

Чтобы определить, принадлежит ли объект определенному типу, используйте оператор -is.

Это будет усложнено, если значения не одного типа, например, если одно из них - [hashtable], а одно из [string].Как вы их объединяете?

Возможно, вы захотите дополнительно обрабатывать несколько типов словарей и сборников для комбинации, в этом случае вы можете использовать оператор -is с интерфейсами, например:

if ($NewTable[$Key] -is [System.Collections.IDictionary]) {
    # handle combining dictionaries
}

И аналогично с ICollection и тому подобное.

Если у вас очень ограниченная область применения этой функции, и вы можете делать предположения о том, что ожидается в значениях, которые вам могут быть легче, на самом деле зависит от ваших вариантов использования.

...