1

I am trying to create an array of HashSets but it always comes out as simply a HashSet. Here is a test script I made:

$arrHashSets = @();

$hs = New-Object System.Collections.Generic.HashSet[string];
$hs2 = New-Object System.Collections.Generic.HashSet[string];

$hs.Add("A");
$hs.Add("B");
$hs.Add("C");

$hs2.Add("A");
$hs2.Add("B");
$hs2.Add("C");

$arrHashSets += $hs;
$arrHashSets += $hs2;

Expected result:

$arrHashSets = [
    {"A", "B", "C"},
    {"A", "B", "C"}
]

Actual result:

$arrHashSets = {"A", "B", "C"}

I tried doing it a few different ways but $arrHashSets always comes out as simply a HashSet rather than an array of type HashSet. What am I doing wrong?

1 Answer 1

3

Replace:

$arrHashSets += $hs
$arrHashSets += $hs2

with:

$arrHashSets = $hs, $hs2

If you do need to build up an array(-like data structure) iteratively:

$lstHashSets = [System.Collections.Generic.List[object]]::new()
foreach ($thisHs in $hs, $hs2) {
  $lstHashSets.Add($thisHs)
}

Note: For simplicity the generic list is [object]-typed here, but you could more strictly type it as [System.Collections.Generic.List[System.Collections.Generic.HashSet[string]]].

However, creating an array / list explicitly isn't strictly needed, given that you can use a statement such as foreach loop as an expression whose multiple outputs PowerShell implicitly captures in an array for you:

$arrHashSets = @(
  foreach ($thisHs in $hs, $hs2) {
    , $thisHs
  }
)

Note:

  • @(...), the array-subexpression operator is necessary to ensure that an array is also constructed in the event that the foreach loop happens to output only a single object.

  • The unary form of ,, the array constructor operator is used to in effect ensure that each hash set is output as a whole. By default, PowerShell would enumerate the hash set's entries, i.e. output them one by one - see this answer for more information.


As for what you tried:

Using += to "extend" an array:

  • is generally to be avoided due to its inefficiency: a new array must be created behind the scenes every time - see this answer.

  • "adds" to the existing array by appending the elements of the RHS, if it is an enumerable, rather than appending the RHS as a whole. Thus, the hash set is enumerated and its elements become direct elements of the resulting, flat array.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks mklement0! I found that your first suggestion didn't make a difference, but using a List instead of an array worked, along with using .Add() instead of +=.
Glad to hear it, @SendETHToThisAddress, though the first suggestion should work as well; try this simplified command: $arr = [System.Collections.Generic.HashSet[string]] ('A', 'B', 'C'), [System.Collections.Generic.HashSet[string]] ('D', 'E', 'F')
@SendETHToThisAddress, I corrected a problem in my answer where I inadvertently used $hs as the iteration variable as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.