Utilities/Convert-ToDictionary.ps1
|
function Convert-ToDictionary { [CmdletBinding()] param( # Pipe your objects or CSV rows in here [Parameter(Mandatory, ValueFromPipeline)] [psobject] $InputObject, # Column/property to use as the key [string] $KeyProperty = 'Name', # Choose the value: the whole object (default), a single property, or a script [string] $ValueProperty, [scriptblock] $ValueScript, # Case sensitivity and duplicate-key behavior [switch] $CaseSensitive, [ValidateSet('Overwrite','Skip','Error','Append')] [string] $OnDuplicate = 'Overwrite' ) begin { $comparer = if ($CaseSensitive) { [StringComparer]::Ordinal } else { [StringComparer]::OrdinalIgnoreCase } $dict = [System.Collections.Generic.Dictionary[string,object]]::new($comparer) } process { if (-not $InputObject.PSObject.Properties[$KeyProperty]) { throw "Key property '$KeyProperty' does not exist on: $($InputObject | Out-String)" } $key = [string]$InputObject.$KeyProperty if ([string]::IsNullOrWhiteSpace($key)) { return } $value = if ($PSBoundParameters.ContainsKey('ValueScript')) { & $ValueScript $InputObject } elseif ($PSBoundParameters.ContainsKey('ValueProperty')) { $InputObject.$ValueProperty } else { $InputObject } if ($dict.ContainsKey($key)) { switch ($OnDuplicate) { 'Overwrite' { $dict[$key] = $value } 'Skip' { } 'Error' { throw "Duplicate key '$key' encountered." } 'Append' { $existing = $dict[$key] if ($existing -isnot [System.Collections.IList]) { $list = [System.Collections.Generic.List[object]]::new() [void]$list.Add($existing) $dict[$key] = $list } [void]($dict[$key]).Add($value) } } } else { $dict[$key] = $value } } end { return $dict } } <# $rows = @( [pscustomobject]@{ Name='Alpha'; Id=1; Path='/a' }, [pscustomobject]@{ Name='Beta' ; Id=2; Path='/b' } ) $byName = $rows | Convert-ToDictionary $byName['alpha'] # returns the Alpha object (case-insensitive by default) $json = ConvertTo-Json -InputObject $byName -Depth 20 $json = ConvertTo-Json -InputObject $byName -Depth 20 #> |