• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 3949
  • Last Modified:

How to stop PowerShell function changing return type of ArrayList or string[]

I'm attempting to return either a .NET ArrayList collection or a string array
(string[]) from a PowerShell function. PowerShells runtime "unravelling" is not
behaving as described, and the various work arounds I've read about don't address
the issue.

What is being returned is also not what I expect or have read about.

The following code returns a System.Array with a count of 6 and the values
0 1 2 A B C. What I want is only 3 values A B C.

function GetArrayOfStrings([string[]] $strings)
{
      # set up a collection to "read them in"
      $stringAryList = New-Object "System.Collections.ArrayList"
      foreach($string in $strings)
      {
            $stringAryList.Add($string)
      }

            $stringAry = $stringAryList.ToArray()
            return $stringAry
}

#main

$stringAry = GetArrayOfStrings(("A", "B", "C"))

foreach($str in $stringAry)
{
      Write-Host $str
}

The returned  values suggest PowerShell is flattening a hash table where 0 1 2 are the index values and A B C the content values.

Attempting to "wrapper" the return using "," or @(,) syntax doesn't improve things much.

      return ,$stringAry
      return @(,$stringAry)
      
Both result in a System.Array containing {0, 1, 2, System.Array} and an output of

0
1
2
A B C

This is better, but the only way to get the string[] as a System.Array is to do the
following:

$actualStringArray = $stringAry[$stringAry.Count-1]

Some of my readings online have suggested the array is unravelled to make it simpler
for human readability or to be used in foreach, but I certainly don't see how...

I have identical problems when attempting to return the ArrayList

Looking for a way to fully defeat the unravelling or a way to use the results in a foreach,
but only for the content values, not the index values.
0
NJThomson
Asked:
NJThomson
  • 2
1 Solution
 
NJThomsonAuthor Commented:
Actually, in further reading, the issue is the following:

In PowerShell, any data that your function or script generates gets sent to the output pipeline, unless something captures that output. Some .NET methods—such as the System.Collections.ArrayList class—produce output, even though you may not expect them to. To prevent these methods from sending data to the output pipeline, either capture the data or cast it to [void]:

PS > $collection = New-Object System.Collections.ArrayList
PS > $collection.Add("Hello")
0
PS > [void] $collection.Add("Hello")

So the solution is to do the [void] trick with the .add function and use the "," operator to send back a single element - the system.array.

The working solution is:

function GetArrayOfStrings([string[]] $strings)
{
      # set up a collection to "read them in"
      $stringAryList = New-Object "System.Collections.ArrayList"
      foreach($string in $strings)
      {
            [Void] $stringAryList.Add($string)
      }

            $stringAry = $stringAryList.ToArray()
            return ,$stringAry
}

#main

$stringAry = GetArrayOfStrings(("A", "B", "C"))

foreach($str in $stringAry)
{
      Write-Host $str
}
0
 
NJThomsonAuthor Commented:
Found a good answer in an online book in Safari....
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now