Reputation: 62746
I want to create a HashSet
using the constructor accepting a collection
But none of my attempts are successful:
C:\> $c = @(1,2,3,4,5)
C:\> New-Object System.Collections.Generic.HashSet[int]
C:\> New-Object System.Collections.Generic.HashSet[int] -ArgumentList @(,$c)
New-Object : Cannot find an overload for "HashSet`1" and the argument count: "1".
At line:1 char:1
+ New-Object System.Collections.Generic.HashSet[int] -ArgumentList @(,$ ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [New-Object], MethodException
+ FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand
C:\> New-Object System.Collections.Generic.HashSet[int] -ArgumentList $c
New-Object : Cannot find an overload for "HashSet`1" and the argument count: "5".
At line:1 char:1
+ New-Object System.Collections.Generic.HashSet[int] -ArgumentList $c
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [New-Object], MethodException
+ FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand
C:\> New-Object System.Collections.Generic.HashSet[int] -ArgumentList @($c)
New-Object : Cannot find an overload for "HashSet`1" and the argument count: "5".
At line:1 char:1
+ New-Object System.Collections.Generic.HashSet[int] -ArgumentList @($c ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [New-Object], MethodException
+ FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand
C:\>
Is there a way to do it?
Upvotes: 7
Views: 11861
Reputation: 701
I realize this is a little old, but you can just cast a list to a set
> $fileTypes = [System.Collections.Generic.HashSet[String]] @(".jpg", ".txt", ".log", ".ini")
> $fileTypes
.jpg
.txt
.log
.ini
> $fileTypes.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True HashSet`1 System.Object
> $fileTypes.Contains(".ini")
True
Upvotes: 6
Reputation: 61068
I have been fiddling with this and it seems this works:
[int[]]$c = 1,2,3,4,5
[System.Collections.Generic.HashSet[int]]::new([System.Collections.Generic.IEnumerable[int]]$c)
You can even leave out the [System.Collections.Generic.IEnumerable[int]]
part here and just do
[int[]]$c = 1,2,3,4,5
[System.Collections.Generic.HashSet[int]]::new($c)
Without declaring the array as [int[]]
it does not work and you'll get the error
Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.Collections.Generic.IEnumerable`1[System.Int32]".
With the typecast [int[]]
, the type for variable c$
is System.Int32[]
and not simply System.Object[]
and that is exactly what the constructor wants.
Hope that helps
Upvotes: 9
Reputation: 7479
apparently you cannot add the entire collection to the HashSet as such. [frown] you need to iterate over the collection and use the .Add()
method. if you add a collection directly, you get that entire collection as one item in the set. ouch!
so you need something like this ...
$HashSetTest = [System.Collections.Generic.HashSet[string]]::new()
$FileExtList = (Get-ChildItem -LiteralPath $env:TEMP -File).Extension
$FileExtList.Where({$_}).ForEach({[void]$HashSetTest.Add($_)})
$HashSetTest.GetType()
'=' * 40
$HashSetTest.Count
'=' * 40
$HashSetTest
'=' * 40
output ...
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True HashSet`1 System.Object
========================================
10
========================================
.csv
.zip
.txt
.json
.log
.ini
.tmp
.bmp
.js
.ani
========================================
Upvotes: -2