programing

해시 테이블을 키-값 쌍으로 열거하거나 키 값 집합으로 해시 테이블을 필터링하는 방법

i4 2023. 8. 4. 22:38
반응형

해시 테이블을 키-값 쌍으로 열거하거나 키 값 집합으로 해시 테이블을 필터링하는 방법

편집자 참고 사항:이 질문은 복잡한 역사를 가지고 있지만 다음과 같이 요약됩니다.
해시 테이블의 항목키-값 쌍으로 열거하는 방법에 대한 자세한 내용은 승인된 답변을 참조하십시오.
주요모음기준으로 해시 테이블을 필터링하는 방법에 대해 알아보려면 다른 답변을 참조하십시오.


XY 문제에 다시 빠진 것 같은데, 처음 질문은 해시 테이블 필터링에 대한 것이었습니다.해시 테이블을 만들기 전에 필터링하는 것이 더 쉽다는 것을 알게 되었습니다.질문에 답했죠?

아니요, Y 문제는 각 키를 반복하고 @briantist가 도와준 값을 사용하는 것이었습니다.

제 목표는 타임스탬프인 키 이름을 루프하고 키 이름을 작업 이름 및 트리거로 사용하여 작업을 예약하는 것입니다.

는 다사용여하 CSV음일해입을 사용하여 Group-Object -AsHashTable -AsString -edit, HashTable을 만들기 전에 CSV를 필터링하면 또는 스크립트 아래의 작업이 더 쉬워진다는 것을 여기서 언급할 가치가 있습니다.

예를 들어,

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

여기에 몇 가지 옵션이 있습니다.

키를 통해 열거하는 중:

foreach ($key in $var.Keys) {
    $value = $var[$key]
    # or
    $value = $var.$key 
}

키-값 쌍 열거(검색했지만 효과적으로 사용되지 않을 수 있음):

foreach ($kvp in $var.GetEnumerator()) {
    $key = $kvp.Key
    $val = $kvp.Value
}

배열(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[]

일치하는 키-값 쌍을 추가로 처리하려면 다음으로 파이프 연결합니다.%(ForEach-Object및 access ) 및세스액$_.Key그리고.$_.Valuevalue):

$ht.GetEnumerator()  | ? Key -in 'one', 'two' | 
  % { "Value for key '$($_.Key)': $($_.Value)" }

파이프라인 대신 보다 효율적인 루프를 사용하는 동등한 명령:

foreach ($key in $ht.Keys) { 
  if ($key -in 'one', 'two') { "Value for key '$($key)': $($ht.$key)" }
}

참고: PSv2의 경우:
연자-in지원되지 할 수 .-contains대신 피연산자가 스왑됩니다.
'one', 'two' -contains $key
파프라인서에, 용사이를 합니다.Where-Object { 'one', 'two' -contains $_.Key }

샘플 해시 테이블을 사용하면 다음을 얻을 수 있습니다.

Value for key 'two': 2
Value for key 'one': 1

출력의 키 순서가 정의 순서와 어떻게 다른지 주목하십시오. PSv3+에서는 순서가 지정된 해시 테이블을 만들 수 있습니다.[ordered] @{ ... }순서를 합니다.을 클릭하여 정의 순서를 보존합니다.

위에서 사용된 키 필터링 기술은 리터럴 키 배열에 의한 필터링에 제한되지 않습니다. 모든 (문자열) 컬렉션은 의 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)" }

# `foreach` loop equivalent:
foreach ($key in $htInput.Keys) {
  if ($key -in $htFilterKeys.Keys) { "Value for key '$($key)': $($htInput.$key)" }
}

결과는 정적 필터 키 배열의 예와 동일합니다.

마지막으로 해시 테이블을 필터링하거나 필터링된 항목만 사용하여 새 해시 테이블을 생성하려면 다음을 수행합니다.

# *In-place* Updating of the hashtable.
# Remove entries other than the ones matching the specified keys.
# Note: The @(...) around $ht.Keys is needed to clone the keys collection before
# enumeration, so that you don't get an error about modifying a collection
# while it is being enumerated.
foreach ($key in @($ht.Keys)) { 
  if ($key -notin 'one', 'two') { $ht.Remove($key) } 
} 

# Create a *new* hashtable with only the filtered entries.
# By accessing the original's .Keys collection, the need for @(...) is obviated.
$htNew = $ht.Clone()
foreach ($key in $ht.Keys) { 
  if ($key -notin 'one', 'two') { $htNew.Remove($key) }
} 

부차적으로:

의 기본 출력 형식:[System.Collections.DictionaryEntry](따라서 해시 테이블([System.Collections.Hashtable]) 열 이름 사용Name보다는Key;Name별칭 속성으로 정의됩니다.Key의 일부가 아닌 PowerShell이 추가했습니다.NET 유형 정의, 사용하여 확인
@{ one = 1 }.GetEnumerator() | Get-Member).

언급URL : https://stackoverflow.com/questions/37635820/how-can-i-enumerate-a-hashtable-as-key-value-pairs-filter-a-hashtable-by-a-col

반응형