Steps to reproduce
$g = @{}
$g["foo"] = 1
$g["bar"] = 1
$g["foo"] # returns 1
$g."foo" # returns 1
$h = write-output $g -NoEnumerate
$h["foo"] # returns $null
$h."foo" # returns 1
$h["bar"] # returns $null
$h."bar" # returns 1
$h.count # returns 1
$($h.keys | measure).count # returns 2
$f = write-output $g
$f["foo"] # returns 1
$f."foo" # returns 1
$f["bar"] # returns 1
$f."bar" # returns 1
$f.count # returns 2
Expected behavior
$h["foo"] # returns 1
$h.count # returns 2
Actual behavior
$h["foo"] # returns $null
$h.count # returns 1
Environment data
Name Value
---- -----
PSVersion 7.1.0
PSEdition Core
GitCommitId 7.1.0
OS Microsoft Windows 10.0.19042
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
Notes
I thought I would use end { Write-Output $Result -NoEnumerate } to be safe for ConvertTo-Dictionary the way I do to ensure an empty HashSet is returned by ConvertTo-HashSet when pipeline input is empty, but it turns out you must use end { $Result } or you get back a broken Hashtable.
Maybe this is expected behavior somehow, but I don't understand what $h is and how $h."foo" and $h."bar" both work even though $h.count is 1. And why $h.keys gives 2 items, while $h.count is 1. I guess $h is being unrolled and that is how it is working. Still, not what I would have expected from -NoEnumerate.
<#
.SYNOPSIS
Convert a stream of objects to a Dictionary
.EXAMPLE
$services = Get-Service | ConvertTo-Dictionary {$_.Name} {$_.DisplayName}
#>
function ConvertTo-Dictionary {
param(
[ScriptBlock]$KeyExpression,
[ScriptBlock]$ValueExpression = { $_ }
)
begin { $Result = @{} }
process { $Result[(&$KeyExpression)] = (&$ValueExpression) }
end { $Result }
}
<#
.SYNOPSIS
Convert a stream of objects to a HashSet
.EXAMPLE
$services = get-service | select -expandproperty Name -first 10 | ConvertTo-HashSet
$null -eq $services # False
$Services = get-service | select -expandproperty Name -first 0 | ConvertTo-HashSet
$null -eq $services # False
#>
function ConvertTo-HashSet {
begin { $hashSet = [System.Collections.Generic.HashSet[String]] @() }
process {
$hashSet.add($_) | Out-Null
}
end { Write-Output -NoEnumerate $hashSet }
}
Steps to reproduce
Expected behavior
$h["foo"] # returns 1$h.count # returns 2Actual behavior
$h["foo"] # returns $null$h.count # returns 1Environment data
Notes
I thought I would use
end { Write-Output $Result -NoEnumerate }to be safe forConvertTo-Dictionarythe way I do to ensure an empty HashSet is returned byConvertTo-HashSetwhen pipeline input is empty, but it turns out you must useend { $Result }or you get back a broken Hashtable.Maybe this is expected behavior somehow, but I don't understand what $h is and how $h."foo" and $h."bar" both work even though $h.count is 1. And why $h.keys gives 2 items, while $h.count is 1. I guess $h is being unrolled and that is how it is working. Still, not what I would have expected from -NoEnumerate.