In many real world scenarios you work with large collections of numbers. VB.Net has several functions for analyzing these collections, such as Sum, Count, Average, Min, Max. This example adds several more functions:

  • Median: This is the midpoint number in the ASC sorted collection
  • ModeThis is the most frequent number(s) in the collection
  • RangeThe difference between Max and Min
  • IQR: The difference between the third Quartile (Q3) and the first Quartile (Q1)
  • Q1The Median of the first half of the sorted collection
  • Q3:  The Median of the second half of the sorted collection
  • StdDev: A measure of how spread the numbers are.

These are overloaded for use with collections of all standard numeric datatypes.

An Example of the Overloaded Functions

#Region "     Byte"
    Public Function Median(l As IEnumerable(Of Byte)) As Decimal
        l = l.OrderBy(Function(b) b)
        If l.Count Mod 2 = 1 Then 'odd count
            Return CDec(l(CInt(Math.Floor(l.Count / 2))))
        Else 'even count
            Return CDec((l(l.Count \ 2 - 1) + l(l.Count \ 2)) / 2)
        End If
    End Function
    Public Function Mode(l As IEnumerable(Of Byte)) As String
        Dim occurrences As New Dictionary(Of Byte, Integer)
        For x As Integer = 0 To l.Count - 1
            If occurrences.ContainsKey(l(x)) Then
                occurrences(l(x)) += 1
                occurrences.Add(l(x), 1)
            End If
        Return String.Join(", ", occurrences.Where(Function(kvp1) kvp1.Value = occurrences.Max(Function(kvp2) kvp2.Value)).Select(Function(kvp3) kvp3.Key.ToString).ToArray)
    End Function
    Public Function Range(l As IEnumerable(Of Byte)) As Byte
        Return l.Max - l.Min
    End Function
    Public Function IQR(l As IEnumerable(Of Byte)) As Decimal
        Return Q3(l) - Q1(l)
    End Function
    Public Function Q1(l As IEnumerable(Of Byte)) As Decimal
        Return quartiles(l)
    End Function
    Public Function Q3(l As IEnumerable(Of Byte)) As Decimal
        Return quartiles(l, False)
    End Function
    Private Function quartiles(l As IEnumerable(Of Byte), Optional Q1 As Boolean = True) As Decimal
        Dim count As Integer = l.Count
        l = l.OrderBy(Function(x) x)
        Dim firstHalf As New List(Of Decimal)
        Dim secondHalf As New List(Of Decimal)
        Dim half As Integer
        If count Mod 2 = 1 Then 'odd count
            half = CInt(Math.Floor(count / 2))
        Else 'even count
            half = count \ 2
        End If
        firstHalf.AddRange(Array.ConvertAll(l.Cast(Of Byte).Take(half).ToArray, Function(b) CDec(b)))
        secondHalf.AddRange(Array.ConvertAll(l.Cast(Of Byte).Skip(count - half).ToArray, Function(b) CDec(b)))
        Return If(Q1, Median(firstHalf), Median(secondHalf))
    End Function
    Public Function StdDev(l As IEnumerable(Of Byte), Optional population As Boolean = True) As Decimal
        Dim mean As Decimal = l.Average(Function(x) CDec(x))
        Dim squaredDifference() As Decimal = Array.ConvertAll(l.ToArray, Function(x As Byte) CDec((x - mean) ^ 2))
        Return If(population, CDec(Math.Sqrt(squaredDifference.Average)), CDec(Math.Sqrt(minusOneAverage(squaredDifference))))
    End Function
#End Region