Преобразование хэш-таблицы в массив строк

Как преобразовать хэш-таблицу в массив строк? Предположим, что $l_table - хэш-таблица. Если я попробую

$l_array = $l_table | format-table

тогда $l_array - это массив, но массив объектов FormatEntryData. Если я делаю

[string[]]$l_array = $l_table | format-table

тогда $l_array - это массив строк, но все строки - "Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData". Если я попробую

$l_array = $l_table | out-string

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

Ответ 1

[string[]]$l_array = $l_table | out-string -stream

Ответ 2

Собственный ответ Дэвида И. Макинтоша работает хорошо, но следует отметить, что элементы результирующего массива соответствуют всем строкам вывода по умолчанию, который включает в себя:

  • пустые ведущие и завершающие строки
  • две строки заголовка (строка с именами столбцов и разделительной линией)

Out-String просто отправляет то, что вы обычно видите в консоли (терминале), в строку, по умолчанию в виде одной строки, а -Stream - как массив строк.

Здесь вариация комментария Дэвида, которая удаляет как заголовок, так и пустые строки:

[string[]] $l_array = ($l_table | out-string -stream) -notmatch '^$' | select -Skip 2

Остальная часть этого ответа показывает , как управлять полученным строковым представлением; для краткости используется синтаксис PS v3 +.

Примечание. Для наглядности хэш-таблица с образцом ввода называется $ht (not $l_table) в следующих примерах.

  • Получить все ключи в виде массива строк:

    $ht.Keys | % ToString
    
  • Получите все значения как строковый массив:

    $ht.Values | % ToString
    
  • Получить пользовательское представление пар ключ-значение, в формате <key>=<value>; обратите внимание, что .GetEnumerator() необходим для отправки пар ключ-значение по отдельности через канал; по умолчанию PowerShell передает хэш-таблицу в целом:

    $ht.GetEnumerator()  | % { "$($_.Name)=$($_.Value)" }
    

Обратите внимание, что в то время как .ToString(), который также применяется неявно во время интерполяции, хорошо работает со встроенными типами .NET, другие типы будут просто полностью печатать их полное имя типа, если их метод .ToString() не переопределен, чтобы вернуть более значимое пользовательское представление (которое, к счастью, часто имеет место с типами, возвращаемыми командлетами PowerShell).

Простой пример выбора свойства значения для его представления в строке:

# Sample hashtable containing a value of a non-built-in type,
# [System.Diagnostics.Process]    
$ht = @{ one = 1; two = $(Get-Process -ID $PID) }

# Use the `.Path` property to represent the value.
$ht.GetEnumerator()  | % { "$($_.Name)=$($_.Value.Path)" }

Ответ 3

Хэш - это просто Hashtable, поэтому он имеет ключи и свойство values.

$hash = @{}

$hash["foo"] = "bob"

$hash.Values

$hash.Values | Out-string

Если вы хотите получить перечислитель, он вернет вам keyvaluepair

$hash.GetEnumerator() |%{$_ | out-string}

Ответ 4

Это обычная проблема; Hashtable должен быть получен с помощью любых ключей или значений, но вы не можете получить набор пар - это то, что, в конце концов, является исходной хэш-таблицей. В моем примере хэш-таблица представлена ​​ "Словарем" (вы помните из VBS:-). Однако вам нужно будет определить разделитель для разграничения ключей и значений, в этом случае "Key ↔ Value"

$ARRAY = ( $DICT.Keys | foreach-object { "$_<->$($DICT[$_])"})

Вы даже можете отсортировать ключи, если хотите. В этом случае я меняю значение на значение < --- > Key и сортируется по значениям. Я также немного расширил строку, чтобы сделать более подробным, но разборчивым:

$ARRAY = ( $DICT.Keys | foreach-object { $DICT[$_] + "<--->" + $_} | sort-object)