New-FastLookup.ps1
function New-FastLookup { <# .SYNOPSIS Designed to optimize the speed of searching an array. .DESCRIPTION Improve the speed of looking up a value in an array by creating a hashtable index. Good for looping through very large arrays or CSV files .NOTES Version: 1.2 Author: Miles Gratz Creation Date: April 20, 2017 Purpose/Change: Improve examples .PARAMETER Array A mandatory parameter specifying input array used to create 'FastLookup' .PARAMETER Header An optional parameter specifying the header in the input array used to create 'FastLookup' .OUTPUTS A hashtable, listing the values in the array and their corresponding index .EXAMPLE PS> $array = 1..1000000 $hashtable = New-FastLookup -Array $array Get-FastLookup -Value 2017 -Array $array -Table $hashtable .EXAMPLE PS> # Search for thousand random numbers in an array of one million $array = 1..1000000 $search = 1..1000 | ForEach-Object { Get-Random -Maximum $array.Count } --------------------------------------------------------------- Where-Object Performance Test Measure-Command { $array | Where-Object { $_ -in $search } } Minutes : 2 Seconds : 39 Milliseconds : 658 --------------------------------------------------------------- ForEach Performance Test Measure-Command { foreach ($item in $array){ if ($item -in $search){ $item } } } Minutes : 1 Seconds : 27 Milliseconds : 460 --------------------------------------------------------------- FastLookup Performance Test Measure-Command { $hashtable = New-FastLookup -Array $array foreach ($item in $search){ Get-FastLookup -Value $item -Array $array -Table $hashtable } } Minutes : 0 Seconds : 49 Milliseconds : 933 --------------------------------------------------------------- [NOTE] Performance test on Windows 10 x64 (i5-6200U/8GB/SSD) #> param( [Parameter(Mandatory=$true)] [array]$Array, $Header ) # Identify headers in input array $Headers = $Array | Get-Member -MemberType 'NoteProperty' | Select-Object -ExpandProperty 'Name' # Define empty hashtable and index $HashTable = @{} $Index = 0 #1: Header specified #2: Header exists in array If (($Header -ne $null) -and ($Header -in $Headers)) { # Redefine array with only data from specified Header $Array = $Array.$Header } #1: Header is specified #2: Header does NOT exist in array ElseIf (($Header -ne $null) -and ($Header -notin $Headers)) { # Exit function with error Write-Error "Specified header ($Header) does not exist in input array." Break } #1: Header is NOT specified #2: Array contains multiple Headers ElseIf (($Header -eq $null) -and ($Headers.Count -gt 1)) { # Exit function with error Write-Error "Input array requires the -Header parameter (multiple columns detected)." Break } # Loop through array foreach ($Item in $Array) { # Add index of Item to hashtable # Name Value # ---- ----- # Server1 953 # Server2 1157 Try { $HashTable.Add($Item,$Index) } # Duplicate key detected, add to existing value # Name Value # ---- ----- # Server1 953 # Server2 1157,3325 Catch { $HashTable[$Item] = ($HashTable[$Item],$Index -join ",") } # Increment loop $Index++ } # Output results $HashTable } |