Skip to content

Instantly share code, notes, and snippets.

@ninmonkey
Last active June 7, 2023 00:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ninmonkey/4382a04a5af25a50a8ebfbeafb93ed05 to your computer and use it in GitHub Desktop.
Save ninmonkey/4382a04a5af25a50a8ebfbeafb93ed05 to your computer and use it in GitHub Desktop.
Refactoring ArrayList with as a Modern Array Example

I call it modern, but it fully works on PS5.1 without changes!

tip: abbreviated version using namespaces

In the examples below, if you add a using namespace statement, you can remove Systems.Collections.Generic tip: System is always included, so you can omit that prefix anywhere as well.

using namespace system.collections.generic
[List[Object]]$users = @()

$users.AddRange( @('bob', 'jen', 'sue' ) )
$users | ConvertTo-Json

Json is a quick way to visualize the shape

[
  "bob",
  "jen",
  "sue"
]

As Chris said, no Arrays Needed There, Pwsh Generates Arrays Implicity

Using the @() operator ensures the expression returns an array no values is still an array type This is useful when you call functions like gci or AD users where you might get nothing back.

using the type name [object[]] is similar. The difference is that's applied as a type constraint.

# get an array of 0-to-many number of pscustomobjects
# 0 items will still create an array with a count of 0
[object[]]$AllPrimaryFilesAttributes = @(
    $PrimaryTree | ForEach-Object {
        [PSCustomObject]@{
            FullPath = $_.FullName
            # ...
        }
    }
)

if you want to add items to arrays, use List[Object]

often powershell will implicitly create arrays, when you output items in the pipeline like above In some cases, arrays can simplify your code.

StartingYour code (with the constraint moved)

[Collections.ArrayList]$AllPrimaryFilesAttributes = @()

# then later
$stuff | Foreach-Object { 
    $x = ...
    [void]$allPrimaryFilesAttributes.Add($x)
}

using List[]

Using List[]s is almost identical as a bonus: You never need [void]

[Collections.Generic.List[Object]]$AllPrimaryFilesAttributes = @()
$stuff | Foreach-Object { 
    $x = ...
    $allPrimaryFilesAttributes.Add($x)
}

AddRange( collection ) vs Add( $item )

If you ever have to manually add items, because you want a flat list

# this
foreach($item in $collection) { 
    $list.Add( $item )
} 

# simplifies to 
$list.AddRange( $collection ) 

Great for building native commands

[List[Object]]$pingArgs = @()
$Config = @{ 
   Count = 2
   ResolveNames = $true
}

$pingArgs.Add('www.google.com')

if($Config.Count -gt 0) { 
   $pingArgs.AddRange(@( 
        '-n'
        $Config.Count
   ))
}

if($Config.ResolveNames) { 
   $pingArgs.Add('-a')
} 

#'final args: '
$pingArgs -join ' ' 

& 'ping' @pingArgs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment