Skip to content

Commit

Permalink
🔧 AboutHashtables Fixes (#187)
Browse files Browse the repository at this point in the history
* ♻️ Refactor AboutHashtables pt1

* ♻️ Complete refactor of AboutHashtables

* 🔧 Put 5 back in the table
  • Loading branch information
vexx32 committed May 31, 2019
1 parent f67a246 commit b160923
Showing 1 changed file with 54 additions and 37 deletions.
91 changes: 54 additions & 37 deletions PSKoans/Koans/Foundations/AboutHashtables.Koans.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -34,34 +34,33 @@ Describe 'Hashtables' {
Spectrum = 'Ultraviolet'
}

$Hashtable | Should -BeOfType __
# Values in the hashtable can be retrieved by specifying their corresponding key
$Hashtable['Color'] | Should -Be '__'
$Hashtable['Spectrum'] | Should -Be '__'
'____' | Should -Be $Hashtable['Color']
'____' | Should -Be $Hashtable['Spectrum']

$Hashtable | Should -BeOfType '__'
$____ | Should -BeOfType [hashtable]
}

It 'can be built all in one line' {
$Hashtable = @{Name = 'Bob'; Species = 'Tardigrade'; Weakness = 'Phys'}
$Hashtable = @{ Name = 'Bob'; Species = 'Tardigrade'; Weakness = 'Phys' }

$Hashtable['Species'] | Should -Be '__'
'____' | Should -Be $Hashtable['Species']
}

It 'can be built in pieces' {
$Hashtable = @{}
$Hashtable = @{ }
# By specifying a key, we can insert or overwrite values in the hashtable
$Hashtable['Name'] = 'Hashtable'
$Hashtable['Color'] = 'Red'
$Hashtable['Spectrum'] = 'Infrared'
$Hashtable['Spectrum'] = 'Microwave'

$Hashtable['Color'] | Should -Be '__'
$Hashtable['Spectrum'] | Should -Be '__'
'____' | Should -Be $Hashtable['Color']
'____' | Should -Be $Hashtable['Spectrum']
}

It 'can be built using the Hashtable object methods' {
$Hashtable = @{}
$Hashtable = @{ }
$Hashtable.Add('Name', 'John')
$Hashtable.Add('Age', 52)
$Hashtable.Add('Radiation', 'Infrared')
Expand All @@ -73,6 +72,11 @@ Describe 'Hashtables' {
Context 'Working with Hashtables' {

It 'is a reference type' {
<#
Like many objects, hashtables typically get passed by reference;
assigning the object to another variable does not create a second copy,
only a second way to refer to the original object.
#>
$HashtableOne = @{
Name = 'Jim'
Age = 12
Expand All @@ -81,7 +85,7 @@ Describe 'Hashtables' {
$HashtableTwo = $HashtableOne
$HashtableTwo['Age'] = 21

$HashtableOne['Age'] | Should -Be 12 # Right?
$HashtableOne['Age'] | Should -Be 12 # Or is it?
__ | Should -Be $HashtableTwo['Age']
}

Expand All @@ -97,45 +101,58 @@ Describe 'Hashtables' {
$HashtableTwo['Calories'] = 250
$HashtableTwo['Contents'] = 'Chips'

$HashtableOne['Meal Type'] | Should -Be '__'
'____' | Should -Be $HashtableOne['Meal Type']
__ | Should -Be $HashtableOne['Calories']

$HashtableTwo['Contents'] | Should -Be '__'
'____' | Should -Be $HashtableTwo['Contents']
}

It 'allows you to retrieve a list of keys or values' {
$Hashtable = @{One = 1; Two = 2; Three = 3; Four = 4}
$Hashtable = @{ One = '1'; Two = '2'; Three = '3'; Four = '4' }

$Hashtable.Keys | Should -Be @('__', '__', '__', '__')
$Hashtable.Values | Should -Be @( )
@( 'One', '____', '____', '____' ) | Should -BeIn $Hashtable.Keys
@( '__', '__', '__', '__' ) | Should -BeIn $Hashtable.Values
}

It 'is not ordered' {
# Hashtables are ordered by hashing their keys for extremely quick lookups.
$Hashtable = @{One = 1; Two = 2; Three = 3; Four = 4}
$Hashtable = @{ One = 1; ____ = 2; Three = 3; Four = __ }

<#
You will find your key/value pairs are often not at all in the order you entered them.
Trying to predict the order of the pairs like this can be very difficult.
The following assertions would be highly likely to fail.
$Hashtable.Keys | Should -Be @('One', 'Two', 'Three', 'Four')
$Hashtable.Values | Should -Be @(1, 2, 3, 4)
# You will find your key/value pairs are often not at all in the order you entered them.
# This _probably_ won't pass.
$Hashtable.Keys | Should -Be @('One', 'Two', 'Three', 'Four')
$Hashtable.Values | Should -Be @(1, 2, 3, 4)
The order can and will change again, as well, if the collection is altered.
#>

# The order can and will change again, as well, if the collection is changed.
$Hashtable['Five'] = 5

$Hashtable.Keys | Should -Be @('One', 'Two', 'Three', 'Four', 'Five')
$Hashtable.Values | Should -Be @(1, 2, 3, 4, 5)
$Hashtable.Keys | Should -Not -Be @('One', 'Two', 'Three', 'Four', 'Five')
$Hashtable.Values | Should -Not -Be @(1, 2, 3, 4, 5)

$Hashtable.Keys | Should -BeIn @('____', 'Two', '____', 'Four', 'Five')
}

It 'can be forced to retain order' {
$Hashtable = [ordered]@{One = 1; Two = 2; Three = 3; Four = 4}
$Hashtable = [ordered]@{ One = 1; Two = 2; Three = 3; Four = 4 }

# The [ordered] tag is not in itself properly a type, but transforms our regular hashtable into...
$Hashtable | Should -BeOfType '__'

# Order comes at a price; in this case, lookup speed is significantly decreased with ordered hashtables.
# Does this leave our keys and values in the order you would expect?
@('__', 'Two', '__', '__') | Should -Be $Hashtable.Keys.ForEach{$_}
@(1, , , 4) | Should -Be $Hashtable.Values.ForEach{$_}
<#
Order comes at a price; in this case, lookup speed is significantly decreased with
ordered hashtables.
Does this leave our keys and values in the order you would expect?
#>
@( '__', 'Two', '__', '__' ) | Should -Be $Hashtable.Keys.ForEach{ $_ }
@( 1, , , 4 ) | Should -Be $Hashtable.Values.ForEach{ $_ }

# The [ordered] tag changes the type of the object completely.
'System.____.____.____' | Should -Be $Hashtable.GetType().FullName
}

It 'allows you to remove keys' {
Expand All @@ -149,8 +166,8 @@ Describe 'Hashtables' {
$Hashtable.Remove('One')

__ | Should -Be $Hashtable.Count
$Hashtable.Keys | Should -Be @('__', '__', 'Four')
$Hashtable.Values | Should -Be @( , , 4)
$Hashtable.Keys | Should -BeIn @('__', '__', 'Four')
$Hashtable.Values | Should -BeIn @( , , 4)
}

It 'can check if keys or values are present in the hashtable' {
Expand All @@ -166,18 +183,18 @@ Describe 'Hashtables' {
}

It 'will not implicitly convert keys and lookup values' {
$Hashtable = @{0 = 'Zero'}
$Hashtable = @{ 0 = 'Zero' }

$Hashtable[0] | Should -Be '__'
$Hashtable['0'] | Should -Be '__'
'__' | Should -Be $Hashtable[0]
'__' | Should -Be $Hashtable['0']
}

It 'can access values by using keys like properties' {
$Hashtable = @{0 = 'Zero'; Name = 'Jim'}
$Hashtable = @{ 0 = 'Zero'; Name = 'Jim' }
$Key = '__'

$Hashtable.0 | Should -Be '__'
$Hashtable.$Key | Should -Be 'Jim'
'__' | Should -Be $Hashtable.0
'Jim' | Should -Be $Hashtable.$Key
}
}
}

0 comments on commit b160923

Please sign in to comment.