classes/HashtableUtility.psm1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
class HashtableUtility {

    #####################
    # HIDDEN PROPERTIES #
    #####################

    

    #####################
    # PUBLIC PROPERTIES #
    #####################

    

    #####################
    # CONSTRUCTORS #
    #####################

    

    #####################
    # HIDDEN METHODS #
    #####################

    static
    [pscustomobject]
    NewCompareResult(
        [object]$Key,
        [object]$LValue,
        [object]$Side,
        [object]$RValue
    ){
        return New-Object -Type PSObject -Property @{
            key    = $Key
            lvalue = $LValue
            rvalue = $RValue
            side   = $Side
        }
    }

    #####################
    # PUBLIC METHODS #
    #####################

<#
.SYNOPSIS
Compare two Hashtable and returns an array of differences.
 
.DESCRIPTION
The Compare function computes differences between two Hashtables. Results are returned as
an array of objects with the properties: "key" (the name of the key that caused a difference),
"side" (one of "<=", "!=" or "=>"), "lvalue" an "rvalue" (resp. the left and right value
associated with the key).
 
Adapted from #https://gist.github.com/dbroeglin/c6ce3e4639979fa250cf#file-compare-hashtable-ps1
 
.PARAMETER left
The left hand side Hashtable to compare.
 
.PARAMETER right
The right hand side Hashtable to compare.
 
.EXAMPLE
 
Returns a difference for ("3 <="), c (3 "!=" 4) and e ("=>" 5).
 
[HashtableUtility]::Compare(@{ a = 1; b = 2; c = 3 },@{ b = 2; c = 4; e = 5})
 
.EXAMPLE
 
Returns a difference for a ("3 <="), c (3 "!=" 4), e ("=>" 5) and g (6 "<=").
 
$left = @{ b = 2; c = 4; e = 5; f = $Null; g = $Null }
$right = @{ b = 2; c = 4; e = 5; f = $Null; g = $Null }
 
[HashtableUtility]::Compare($left,$right)
 
#>
    
    static
    [object[]]
    Compare(
        [hashtable]$Left,
        [hashtable]$Right
    ){
        
        [Object[]]$Results = $Left.Keys | % {
            if ($Left.ContainsKey($_) -and !$Right.ContainsKey($_)) {
                [HashtableUtility]::NewCompareResult($_,$Left[$_],"<=",$Null)
            } else {
                $LValue, $RValue = $Left[$_], $Right[$_]
                if ($LValue -ne $RValue) {
                    [HashtableUtility]::NewCompareResult($_,$LValue,"!=",$RValue)
                }
            }
        }
        $Results += $Right.Keys | % {
            if (!$Left.ContainsKey($_) -and $Right.ContainsKey($_)) {
                [HashtableUtility]::NewCompareResult($_,$Null,"=>",$Right[$_])
            } 
        }
        return $Results
    }

    static
    [int32]
    FindDepth(
        [hashtable]$Hashtable
    ){
        return [HashtableUtility]::FindDepth($Hashtable,1)
    }

    static
    [int32]
    FindDepth(
        [hashtable]$Hashtable,
        [int32]$Depth
    ){
        $deepest = $Depth
        foreach($kv in $Hashtable.GetEnumerator()) {
            if($kv.Value -is [hashtable]) {
                $innerDepth = [HashtableUtility]::FindDepth($kv.Value,($Depth + 1))
                if ($innerDepth -gt $deepest) {$deepest = $innerDepth}
            } elseif ($kv.Value -is [system.array]) {
                $arrDepth = $Depth + 1
                if ($arrDepth -gt $deepest) {$deepest = $arrDepth}
                foreach($item in $kv.Value) {
                    if($item -is [hashtable]) {
                        $innerDepth = [HashtableUtility]::FindDepth($item,($arrDepth + 1))
                        if ($innerDepth -gt $deepest) {$deepest = $innerDepth}
                    }
                }
            }
        }
        return $deepest
    }

}