Categories

Some thoughts on hash tables

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

2 Responses to Some thoughts on hash tables

  • Stephen Mills says:

    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

  • 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

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>