-
Notifications
You must be signed in to change notification settings - Fork 1
/
Measure-Average.ps1
97 lines (80 loc) · 2.47 KB
/
Measure-Average.ps1
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
function Measure-Average {
<#
.SYNOPSIS
Calculates the average of an array of numbers
.DESCRIPTION
Allows the user to choose average mean, median,
or mode and returns the numerical result.
.EXAMPLE
Measure-Average @(1,3,44,3,14,6,100)
24.4285714285714
Returns the average (mean)
.EXAMPLE
Measure-Average @(1,3,44,3,14,6,100) Median
6
Returns the median
.EXAMPLE
Measure-Average @(1,3,44,3,14,6,100) Mode
3
Returns the most common item (mode)
.EXAMPLE
Measure-Average @(1,3,44,3,14,6,100,6) Mode
3
6
Returns the most common items (modes)
#>
[CmdletBinding()]
param(
# Array of numbers to average (allow null elements, we remove them in logic)
[Parameter(Mandatory,Position=0)]
[AllowNull()]
[System.Object[]]
$Data,
# Array of numbers to average
[Parameter(Position=1)]
[ValidateNotNull()]
[ValidateSet('Mean','Median','Mode')]
[Alias('Method')]
[string]
$Average = 'Mean'
)
# Ensure no null values are passed
$count1 = ($Data | Measure-Object).Count
$Data = $Data | Where-Object {$null -ne $_}
$count2 = ($Data | Measure-Object).Count
$diffC = $count1 - $count2
if ($count2) {
if ($diffC) {Write-Warning "[Measure-Average] Filtered out $($diffC) null data point(s)"}
} else {
Write-Error 'No values passed to function!'
return
}
switch ($Average) {
'Mean' {
($Data | Measure-Object -Average).Average
}
'Median' {
$Data = $Data | Sort-Object
if ($Data.count % 2) {
#odd
$middleItemIndex = [math]::Ceiling($Data.count/2) - 1
$Data[$middleItemIndex]
} else {
#even
$twoMiddleItems = $Data[$Data.Count/2], $Data[$Data.count/2-1]
($twoMiddleItems | Measure-Object -Average).average
}
}
'Mode' {
$sortedByCount = $Data | Group-Object | Sort-Object -Descending Count
$maxCount = $sortedByCount[0].Count
# Return multiple values is desired when found
$Modes = ($sortedByCount | Where-Object Count -eq $maxCount).Name
$Modes
}
Default {
Write-Error "Unhandled Average: $($Average)"
return
}
}
}#END: function Measure-Average