modules/Helper/StringHelper.psm1

using module '.\DateTimeHelper.psm1'

class StringHelper {

    static [string] getHash([string]$string){

        $_stringAsStream = [System.IO.MemoryStream]::new()

        $_writer = [System.IO.StreamWriter]::new($_stringAsStream)
        $_writer.write($string)
        $_writer.Flush()

        $_stringAsStream.Position = 0

        return (Get-FileHash -InputStream $_stringAsStream).Hash
    }

    static [PSCustomObject[]] groupValueByBlocks([int[]] $values, [int] $intervalBlock, [int] $threshold, [double[]] $percentile, [bool]$formatAsTime) {

        $_cumulativePercentage = 0; $_baseline = ''; $j = 0
        $_remainingLines = 0; $_remainingPercentage = 0; $_analyzedLines = 0

        $_maxBlocks = $values.Count - 1
        for ($i=0; $i -le $_maxBlocks; $i++){
            $_analyzedLines += $values[$i]
        }

        $_retValue = @()
        for ($i=0; $i -le $_maxBlocks; $i++){
            $_percentage = $values[$i] / $_analyzedLines
            $_cumulativePercentage += $_percentage

            $_prevInterval = ''; $_nextInterval = ''; $_interval = ''

            if ($i -eq 0){
                if ($formatAsTime){
                    $_interval = ("{0} < t <= {1}" -f @(([DateTimeHelper]::FormatMilliseconds(0), ([DateTimeHelper]::FormatMilliseconds(($i + 1) * $intervalBlock)))))
                }
                else {
                    $_interval = ("{0} < x <= {1}" -f @(0, (($i + 1) * $intervalBlock)))
                }

            }
            elseif ($i -eq $_maxBlocks){
                if ($_baseline) {
                    if ($formatAsTime){
                        $_prevInterval = ("{0} < t <= {1}" -f @(([DateTimeHelper]::FormatMilliseconds($_baseline), ([DateTimeHelper]::FormatMilliseconds($i * $intervalBlock)))))
                        $_nextInterval = ("t > {0}" -f ([DateTimeHelper]::FormatMilliseconds($i * $intervalBlock)))
                        $_interval = ("t > {0}" -f ([DateTimeHelper]::FormatMilliseconds($_baseline)))
                    }
                    else {
                        $_prevInterval = ("{0} < x <= {1}" -f @($_baseline, (($i * $intervalBlock))))
                        $_nextInterval = ("x > {0}" -f ($i * $intervalBlock))
                        $_interval = ("x > {0}" -f $_baseline)
                    }

                }
                else {
                    if ($formatAsTime){
                        $_interval = ("t > {0}" -f ([DateTimeHelper]::FormatMilliseconds(($i + 1) * $intervalBlock)))
                    }
                    else {
                        $_interval = ("x > {0}" -f (($i + 1) * $intervalBlock))
                    }
                }
            }
            else {
                if ($_baseline) {
                    if ($formatAsTime){
                        $_prevInterval = ("{0} < t <= {1}" -f @(([DateTimeHelper]::FormatMilliseconds($_baseline), ([DateTimeHelper]::FormatMilliseconds($i * $intervalBlock)))))
                        $_nextInterval = ("{0} < t <= {1}" -f @(([DateTimeHelper]::FormatMilliseconds($i * $intervalBlock)), ([DateTimeHelper]::FormatMilliseconds(($i + 1) * $intervalBlock))))
                        $_interval = ("{0} < t <= {1}" -f @(([DateTimeHelper]::FormatMilliseconds($_baseline), ([DateTimeHelper]::FormatMilliseconds(($i + 1) * $intervalBlock)))))
                    }
                    else {
                        $_prevInterval = ("{0} < x <= {1}" -f @($_baseline, ($i * $intervalBlock)))
                        $_nextInterval = ("{0} < x <= {1}" -f @(($i * $intervalBlock), (($i + 1) * $intervalBlock)))
                        $_interval = ("{0} < x <= {1}" -f @($_baseline, (($i + 1) * $intervalBlock)))
                    }
                }
                else {
                    if ($formatAsTime){
                        $_interval = ("{0} < t <= {1}" -f @(([DateTimeHelper]::FormatMilliseconds($i * $intervalBlock)), ([DateTimeHelper]::FormatMilliseconds(($i + 1) * $intervalBlock))))
                    }
                    else {
                        $_interval = ("{0} < x <= {1}" -f @(($i * $intervalBlock), (($i + 1) * $intervalBlock)))
                    }
                }
            }

            if ($values[$i] -ne 0){
                if (($_cumulativePercentage -ge $percentile[$j]) -or ($_percentage -ge $threshold)){
                    if ($_prevInterval){
                        # Split in before and after record
                        $_retValue += ([PSCustomObject]@{PSTypeName='GroupBlock'; interval=$_prevInterval; items=$_remainingLines; `
                            percentage=("{0:P1}" -f $_remainingPercentage); `
                            up_to=("{0:P1}" -f ($_cumulativePercentage - $_percentage)); `
                            above=("{0:P1}" -f (1 - $_cumulativePercentage + $_percentage))})

                        $_retValue += ([PSCustomObject]@{PSTypeName='GroupBlock'; interval=$_nextInterval; items=$values[$i]; `
                            percentage=("{0:P1}" -f $_percentage); `
                            up_to=("{0:P1}" -f $_cumulativePercentage); `
                            above=("{0:P1}" -f (1 - $_cumulativePercentage))})
                    }
                    else {
                        $_retValue += ([PSCustomObject]@{PSTypeName='GroupBlock'; interval=$_interval; items=$values[$i]; `
                            percentage=("{0:P1}" -f ($_percentage + $_remainingPercentage)); `
                            up_to=("{0:P1}" -f $_cumulativePercentage); `
                            above=("{0:P1}" -f (1 - $_cumulativePercentage))})
                    }

                    if ($_cumulativePercentage -ge ($percentile[$j])) { $j += 1 }
                    $_baseline = ''
                    $_remainingPercentage = 0
                    $_remainingLines = 0
                }
                else {
                    if ($_baseline -eq '') {
                        $_baseline = "$($i * $intervalBlock)"
                    }
                    $_remainingPercentage += $_percentage
                    $_remainingLines += $values[$i]
                }
            }
            else {
                if ($_baseline -eq '') {
                    $_baseline = "$($i * $intervalBlock)"
                }
            }
        }

        return $_retValue
    }

    static [string] getMedian([string[]] $array) {

        if ($array.count % 2) {
            #odd
            $median = $array[[math]::Floor($array.count / 2)]
        }
        else {
            #even
            $median = ($array[$array.Count / 2], $array[$array.count / 2 - 1] | Measure-Object -Average).Average
        }
        return $median
    }

    static [string] getMode([string[]] $array) {

        $i=0
        $mode = @()

        foreach ($group in ($array | Group-Object | Sort-Object -Descending count)) {
            if ($group.count -ge $i) {
                $i = $group.count
                $mode += $group.Name
            }
            else {
                break
            }
        }

        return $mode
    }

    static [string] FormatFileSize([int] $size){

        If ($size -gt 1TB) {$_retValue = [string]::Format("{0:N2}TB", $size / 1TB)}
        ElseIf ($size -gt 1GB) {$_retValue = [string]::Format("{0:N2}GB", $size / 1GB)}
        ElseIf ($size -gt 1MB) {$_retValue = [string]::Format("{0:N2}MB", $size / 1MB)}
        ElseIf ($size -gt 1KB) {$_retValue = [string]::Format("{0:N2}KB", $size / 1KB)}
        ElseIf ($size -gt 0) {$_retValue = [string]::Format("{0:N2}B", $size)}
        Else {$_retValue = ""}

        return $_retValue
    }
}