Powershell 에서의 Hash Table은 .NET 의 System.Collections.Hashtable 타입이다. 따라서 동일한 Property와 Method 들을 가지고 있다.
Hash Table은 Key-Value Pair(쌍) 의 Collection 이다. Key 와 Value 쌍으로 있어야 입력 할 수 있다. Value는 null 값이 가능 하지만 Keys는 null 값이 허용되지 않는다.
Hash Table 생성
Hash Table 개체는 New-Object cmdlet 또는 @{ } 로 생성 할 수 있다.
다음은 동일한 동작이다.
$HashA = New-Object -TypeName System.Collections.Hashtable $HashB = @{}
@{ }을 이용해 생성과 함께 초기 값들을 입력 할 수 있다.
@{“Key”=”Value”;”Key”=”Value”} 형식으로 입력 한다.
# @{"Key"="Value";"Key"="Value"} $Hash = @{"Alpha"=1111; "Bravo"=2222; "Charlie"=3333}
생성한 $Hash를 확인 해 보자.
PS > $Hash Name Value ---- ----- Charlie 3333 Alpha 1111 Bravo 2222
Hash Table 의 특성상 순서는 신경 쓰지 않는다. 필요하면 정렬해서 쓰도록 하자.
사용 예
$Hash = @{"Alpha"=1111; "Bravo"=2222; "Charlie"=3333} $Hash.Count # 3 $Hash.Add("Delta", 4444) # Element 추가. $Hash.Count # 4 $Hash.Add("Bravo", 5555) # Error - 이미 존재 하는 Key. $Hash.Remove("Bravo") # Bravo Key를 가진 Element 삭제. $Hash.Contains("Charlie") # True - Charlie 라는 Key를 포함하고 있다. $Hash.Contains("Bravo") # False - Bravo 라는 Key는 존재하지 않는다.
Key, Value의 접근
Key에 해당하는 Value를 얻기 위해서는 [ ]연산자를 이용하여 접근 한다.
$Value = $Hash["Key"]
Powershell 에서 Hash Table 개체는 포함하고 있는 Key들의 Collection과 Value들의 Collection을 제공 한다.
.Values를 이용하여 Value들을 순회
foreach ($value in $Hash.Values) { Write-Host $value }
.Keys를 이용하여 key들을 순회
foreach ($key in $Hash.Keys) { Write-Host $key }
.Keys를 이용하여 key와 value를 순회
foreach ($key in $Hash.Keys) { Write-Host ("{0} - {1}" -f $key, $Hash[$key]) }
Hash Table 순회시 주의 사항
.Net과 다르게 Powershell 에서는 .Keys 나 .Values를 사용하지 않고 직접 HashTable 개체에 순회를 시도 할 때에는 Collection으로 인식하지 않는다. foreach 또는 pipeline 에서 HashTable 타입을 Collection으로 착각하지 말자.
예를 들어 .NET C# 에서는
Hashtable openWith = new Hashtable(); openWith.Add("txt", "notepad.exe"); openWith.Add("bmp", "paint.exe"); openWith.Add("dib", "paint.exe"); openWith.Add("rtf", "wordpad.exe"); int count = 0; foreach( DictionaryEntry de in openWith ) { Console.WriteLine("Key = {0}, Value = {1}", de.Key, de.Value); count++; } Console.WriteLine(count); // 4
foreach로 HashTable을 접근하여 DictionaryEntry에서 .Key와 .Value에 접근하였다.
count 변수는 4번 증가 하였다.
하지만 Powershell 에서는
$Hash = @{"Alpha"=1111; "Bravo"=2222; "Charlie"=3333} [int]$counter = 0 foreach ($item in $Hash) { Write-Host ("Key = {0}, Value = {1}" -f $item.Key , $item.Value) $counter++ } $counter # 1
다음과 같은 출력을 볼 것이다.
Key = , Value = 1
Key와 Value 가 비어 있는 것은 .Key .Value 맴버가 없기 때문에 $null 이 출력 된 것이다. 이 말은 곧 $item 변수가 DictionaryEntry 타입이 아니라는 뜻이다. 게다가 count 가 한번만 증가 한것으로 보아 HashTable 타입의 개체는 Collection으로 인식 하지 않는다. 즉 위 코드에서 foreach 내부의 $item은 HashTable 타입이다.
다음과 같이 확인해보면 더욱 명확하게 이해 할 수 있다.
$Hash = @{"Alpha"=1111; "Bravo"=2222; "Charlie"=3333} foreach ($item in $Hash) { $item.GetType(); }