programing

PowerShell의 'forach' 루프에서 해시 테이블 값 업데이트

goodsources 2023. 7. 30. 17:45
반응형

PowerShell의 'forach' 루프에서 해시 테이블 값 업데이트

해시 테이블을 루프하여 각 키의 값을 5로 설정하려고 하는데 PowerShell에서 다음 오류가 발생합니다.

$myHash = @{}
$myHash["a"] = 1
$myHash["b"] = 2
$myHash["c"] = 3

foreach($key in $myHash.keys){
    $myHash[$key] = 5
}

컬렉션을 통해 열거하는 동안 오류가 발생했습니다.

Collection was modified; enumeration operation may not execute..
At line:1 char:8
+ foreach <<<< ($key in $myHash.keys){
    + CategoryInfo          : InvalidOperation: (System.Collecti...tableEnumer
   ator:HashtableEnumerator) [], RuntimeException
    + FullyQualifiedErrorId : BadEnumeration

무엇이 이 문제를 어떻게 해결합니까?

Hashtable을 열거하는 동안 수정할 수 없습니다.다음과 같은 작업을 수행할 수 있습니다.

$myHash = @{}
$myHash["a"] = 1
$myHash["b"] = 2
$myHash["c"] = 3

$myHash = $myHash.keys | foreach{$r=@{}}{$r[$_] = 5}{$r}

편집 1

이 방법이 더 간단합니까?

$myHash = @{}
$myHash["a"] = 1
$myHash["b"] = 2
$myHash["c"] = 3

foreach($key in $($myHash.keys)){
    $myHash[$key] = 5
}

이것을 달성하는 훨씬 더 간단한 방법이 있습니다.해시 테이블이 참조 유형 변수이기 때문에 열거하는 동안 값을 변경할 수 없습니다.의 이야기와 정확히 같습니다.그물.

다음 구문을 사용하여 이 문제를 해결합니다.다음을 사용하여 키 컬렉션을 기본 배열로 변환하고 있습니다.@()표기법키 컬렉션의 복사본을 만들고 해당 배열을 참조하면 이제 해시 테이블을 편집할 수 있습니다.

$myHash = @{}
$myHash["a"] = 1
$myHash["b"] = 2
$myHash["c"] = 3

foreach($key in @($myHash.keys)){
    $myHash[$key] = 5
}

이 예에서는 전체 해시 테이블을 복제할 필요가 없습니다.키 컬렉션을 배열에 강제로 지정하여 열거하기만 하면 됩니다.@(...)충분합니다.

foreach($key in @($myHash.keys)) {...

사용하다clone:

각($myHash.clone().key의 $key){$myHash[$key] = 5}

또는 한 줄기 선에서:

$myHash =($myHash.clone()).키 | % {} {$myHash[$_] = 5} {$myHash}

PowerShell은 처음 사용하는 제품이지만, 내장된 기능을 사용하는 것이 더 읽기 쉽기 때문에 매우 좋아합니다.이것이 GetEnumerator와 Clone을 사용하여 문제를 해결하는 방법입니다.이 접근 방식을 사용하면 수정 목적으로 기존 해시 값($.value)을 참조할 수도 있습니다.

$myHash = @{}
$myHash["a"] = 1 
$myHash["b"] = 2
$myHash["c"] = 3

$myHash.Clone().GetEnumerator() | foreach-object {$myHash.Set_Item($_.key, 5)}

창의력을 발휘해야 합니다!

$myHash = @{}
$myHash["a"] = 1
$myHash["b"] = 2
$myHash["c"] = 3

$keys = @()
[array] $keys = $myHash.keys

foreach($key in $keys)
{
    $myHash.Set_Item($key, 5)
}

$myHash

Name                         Value
----                         -----
c                              5
a                              5
b                              5

앞의 답변에서 언급한 바와 같이,clone가는 길입니다.해시의 null 값을 "Unknown"(알 수 없음)으로 바꿔야 했는데 이 한 줄기가 그 역할을 합니다.

($record.Clone()).keys | %{if ($record.$_ -eq $null) {$record.$_ = "Unknown"}}
$myHash = @{
    Americas = 0;
    Asia = 0;
    Europe = 0;
}

$countries = @("Americas", "Asia", "Europe", "Americas", "Asia")

foreach($key in $($myHash.Keys))
{
    foreach($Country in $countries)
    {
        if($key -eq $Country)
        {
            $myHash[$key] += 1
        }
    }
}

$myHash
$myHash = @{
    Americas = 0;
    Asia = 0;
    Europe = 0;
}

$countries = @("Americas", "Asia", "Europe", "Americas", "Asia")

foreach($key in $($myHash.Keys))
{
    foreach($Country in $countries)
    {
        if($key -eq $Country)
        {
            $myHash[$key] += 1
        }
    }
}

배열 요소가 해시 키와 일치하는 경우 해시 값을 업데이트합니다.

각 루프에 대해 해시 테이블을 업데이트하면 열거자가 자체적으로 비활성화되는 것 같습니다.새로운 해시 테이블을 작성하여 이 문제를 해결했습니다.

$myHash = @{}
$myHash["a"] = 1
$myHash["b"] = 2
$myHash["c"] = 3

$newHash = @{}
foreach($key in $myHash.keys){
    $newHash[$key] = 5
}
$myHash = $newHash

언급URL : https://stackoverflow.com/questions/5879871/updating-hash-table-values-in-a-foreach-loop-in-powershell

반응형