1

I'm trying to partition out chunks of work using PowerShell (5.0) and am having a hard time instantiating a multidimensional array.

$n = 456;
$MaxChunks = 6;

$Chunks = @();

for($x = 0; $x -lt $MaxChunks; $x++)
{    
    Write-Host "Creating chunk $x"    
    $Chunks += @();
}

$Chunks.Count always returns 0 and I cannot access anything in $Chunks by index (i.e. $Chunks[0] is null).

Ultimately, my goal is to access the array located at $Chunks[$i] and add multiple System.Data.DataRow objects to it. However, as I've said, I'm not able to access the array at that index because that array is never instantiated.

I've read through this and this but am not quite able to translate the hashtable scenario to my situation.

5
  • 1
    Did you see this answer from your second link? That's the probably the information you need. Commented Jan 31, 2017 at 18:36
  • 2
    $Chunks = ,@() * $MaxChunks Commented Jan 31, 2017 at 19:07
  • @PetSerAl, it'll reuse the same object instance. Although it won't be a problem if the OP uses += to populate those sub-arrays since += recreates the array. Commented Jan 31, 2017 at 19:39
  • @wOxxOm Zero length arrays are effectively read-only, so (apart from reference equality) it does not matter if it reused or not. Commented Jan 31, 2017 at 19:41
  • This question may have an answer. Commented Sep 25, 2018 at 21:03

2 Answers 2

5

Alternatively:

[System.Array] $chunks = [System.Array]::CreateInstance( [Int32], 3, 3 );

$chunks[0,0];
0

Not native PS, but works.

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

Comments

5
  • Replicate an empty array.
    The same object is referenced in each element but in this particular case it's not a problem because standard arrays are read-only and recreated when elements are added via +=.

    $Chunks = ,@() * $MaxChunks
    
  • Collect foreach output:

    $Chunks = @(foreach ($x in 1..$MaxChunks) { ,@() })
    

    The outer @() handles a theoretically possible case when $MaxChunks = 1.
    You can use a more verbose (arguably slower) Write-Output -NoEnumerate:

    $Chunks = @(foreach ($x in 1..$MaxChunks) { echo -NoEnumerate @() })
    
  • And in case the sub-arrays will be modified a lot, use ArrayList instead of +=:

    $Chunks = @(foreach ($x in 1..$MaxChunks) { ,[Collections.ArrayList]@() })
    

    and later:

    $Chunks[0].Add($something) >$null
    

P.S. Don't use += to generate entire arrays from scratch regardless of its size as it's a terrible method that recreates and copies the entire array each time; there's a much faster and simpler output collection via loop statements such as foreach, for, while; there's ArrayList object for the case of frequent non-sequential modifications of an array.

4 Comments

BTW, why do you use echo -NoEnumerate instead of ,?
Mainly because it's more verbose so less chance for a typo/overlook. Also, internally ,@() creates two arrays, the outer one is unrolled (the overhead is negligible though so I guess I'll add it in the answer).
Also, internally ,@() creates two arrays The same applies for echo -NoEnumerate @() too. And it also have overhead of instantiating Write-Output cmdlet, parameter binding, etc.
Sounds convincing.

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.