Как я могу перечислить хэш-таблицу в качестве пар ключ-значение/фильтровать хеш-таблицу по набору ключевых значений
Примечание редактора:
Этот вопрос имеет сложную историю, но сводится к следующему:
* Чтобы узнать, как перечислить записи хэш-таблицы по ее парам ключ-значение, см. принятый ответ.
* Чтобы узнать, как фильтровать хэш-таблицу с помощью набора ключевых значений, см. другой ответ.
Я думаю, что снова попал в проблему X Y, мой первоначальный вопрос касался фильтрации хэш-таблицы. Я обнаружил, что проще фильтровать до создания хеш-таблицы. Ответ на вопрос, верно?
Нет, проблема Y заключалась в циклизации каждого ключа и использовании значений, которые мне помог @briantist.
Моя цель - перебрать имена ключей, которые являются отметками времени, и запланировать задачу с использованием имени ключа в качестве имени задачи и триггера.
Я создаю хэш-таблицу из файла CSV с помощью Group-Object -AsHashTable -AsString
-edit, стоит упомянуть здесь, что фильтрация CSV до создания HashTable упрощает работу с Pipeline
или script.
В качестве примера:
Import-CSV (ls -path D:\ -Filter source*.csv | sort LastWriteTime | Select -Last 1).FullName |
where {$_.TimeCorrected -ne 'ManualRebootServer'} |
group TimeCorrected -AsHashTable -AsString
Я пытаюсь перебрать имена ключей и отобразить имена ключей, используя:
$var = Import-Csv csv123.csv | Group-Object Value1 -AsHashTable -AsString
foreach ($key in $var.Keys){"The key name is $key"}
#Create a scheduled task named and triggered based on the HashTable keyname
#test test test
foreach ($key in $var.keys){IF($key -ne 'ManualRebootServer'){"Register-ScheduledJob"}}
Я просто не уверен, как получить значения из интересующих меня ключей.
Я нашел следующие работы, но только когда я вводил имя ключа вручную. Я просто не знаю, как объединить оба цикла.
($val.GetEnumerator() | Where {$_.key -eq '06-11-16 18:00'} | ForEach-Object { $_.value }).Server
Ответы
Ответ 1
У вас есть несколько вариантов.
Перечисление через клавиши:
foreach ($key in $var.Keys) {
$value = $var[$key]
# or
$value = $var.$key
}
Перечисление пар ключ-значение (которое вы обнаружили, но не можете эффективно использовать):
foreach ($kvp in $var.GetEnumerator()) {
$key = $kvp.Key
$val = $kvp.Value
}
Ответ 2
Чтобы дополнить бриантистский полезный ответ, сосредоточив внимание на фильтрации хэш-таблицы массивом ключевых значений (синтаксис PSv3 +):
# Sample hashtable.
$ht = @{ one = 1; two = 2; three = 3 }
# Filter it by an array of key values; applying .GetEnumerator() yields an array
# of [System.Collections.DictionaryEntry] instances, which have
# a .Key property and a .Value property.
$ht.GetEnumerator() | ? Key -in 'one', 'two'
# Similarly, the *output* - even though it *looks* like a hashtable -
# is a regular PS *array* ([Object[]]) containing [System.Collections.DictionaryEntry]
# entries (2 in this case).
$arrFilteredEntries = $ht.GetEnumerator() | ? Key -in 'one', 'two'
$arrFilteredEntries.GetType().Name # -> Object[]
# Use the following technique to reassemble the filtered entries into
# a single output hashtable:
$htFiltered = @{}
$ht.GetEnumerator() | ? Key -in 'one', 'two' | % { $htFiltered.Add($_.Key, $_.Value) }
Для дальнейшей обработки пар пар ключ-значение просто подключитесь к %
(ForEach-Object
) и получите доступ к $_.Key
и $_.Value
(значение):
$ht.GetEnumerator() | ? Key -in 'one', 'two' |
% { "Value for key '$($_.Key)': $($_.Value)" }
С образцом хеш-таблицы это дает:
Value for key 'one': 1
Value for key 'two': 2
Используемая выше технология фильтрации ключей не ограничивается фильтрацией массивами буквенных ключей; любая (строка) коллекция будет выполнять как RHS операнда -in
, например, в коллекции .Keys
другой хеш-таблицы:
# Sample input hashtable.
$htInput = @{ one = 1; two = 2; three = 3 }
# Hashtable by whose keys the input hashtable should be filtered.
# Note that the entries' *values* are irrelevant here.
$htFilterKeys = @{ one = $null; two = $null }
# Perform filtering.
$htInput.GetEnumerator() | ? Key -in $htFilterKeys.Keys |
% { "Value for key '$($_.Key)': $($_.Value)" }
Результат такой же, как в примере с массивом статических ключей.
В стороне:
Формат вывода по умолчанию для [System.Collections.DictionaryEntry]
(и, следовательно, hashtables ([System.Collections.Hashtable]
) использует имя столбца Name
, а не Key
; Name
определяется как свойство псевдонима Key
, добавленное PowerShell (it не является частью [System.Collections.DictionaryEntry]
Определение типа .NET, проверьте с помощью
@{ one = 1 }.GetEnumerator() | Get-Member
).