I need to test the existence of an element in a hash table.
First create a hash table
$myht = DATA {
ConvertFrom-StringData -StringData @’
1 = aaaaaaa
2 = bbbbbbb
3 = ccccccc
4 = ddddddd
5 = eeeeeee
‘@
}
I tend to create them using ConvertFrom-StringData as it simplifies typing, I have a template for this and its easy to see what entries I’m making
lets see what happens
"1 = $($myht[‘1’])"
"6 = $($myht[‘6’])"
1 = aaaaaaa
6 =
The first test works as we would expect but interestingly we don’t get an error message when we try to access an element that doesn’t exist
So we can build on that
"1","6" | foreach {
if ($($myht[$_])){
"$_ = $($myht[$_])"
}
else {
"$_ not found"
}
}
a simple logic test shows if the element exists or not and we can branch from there
Life gets a bit more interesting when we are dealing with boolean and NULL values. In this case I built hash table with three values as shown, true, false and null
$myht2 = @{"1"=$true; "2"=$false; "3"=$null}
if we run the same if statement
"1","2", "3", "4" | foreach {
if ($myht2[$_]){
"$_ = $($myht2[$_])"
}
else {
"$_ not found"
}
}
we get this
1 = True
2 not found
3 not found
4 not found
which isn’t quite true
So lets try a switch statement
"1","2", "3", "4" | foreach {
$x = $_
switch ($myht2[$_]){
$true {"$x = $($myht2[$x])"}
$false {"$x is false"}
$null {"$x is null"}
default {"$x not found"}
}
}
1 = True
2 is false
3 is null
4 is null
Answers for 1,2 & 3 are OK but we can’t differentiate between an element that is null or a non-existent element.
The answer is that we need to think carefully about the data in our hash tables and how we test for existance
By: Stephen Mills on May 28, 2012 at 8:12 pm
I always use the ContainsKey method. It avoids all the problems you mentioned. If it is there, it returns true, otherwise false.
1..6 | % { “$_ Exists $($MyHT.ContainsKey(“$_”))” }
1 Exists True
2 Exists True
3 Exists True
4 Exists True
5 Exists True
6 Exists False
1..4 | % { “$_ Exists $($MyHT2.ContainsKey(“$_”))” }
1 Exists True
2 Exists True
3 Exists True
4 Exists False
By: Chris Warwick on May 29, 2012 at 9:03 am
Hi Richard,
Try the .ContainsKey() method:
PS> $ht=@{“1″=$true;”2″=$false;”3″=$null}
PS> ‘1’,’2′,’3′,’4’|%{$myht2.containskey($_)}
True
True
True
False
PS>
hth!
Cheers,
Chris