0

Regarding this topic, I've so far found two questions here which relate to my question, but not fully. I have found how to initialize a large array, here. Additionally, I've found how to declare a multi-dimensional array, here. I've yet to find a solution which covers how to both declare AND initialize a multi-dimensional array. In my case, I need an array[10][10] with all elements initialized to zero. Currently I do this as follows:

$array = @(
    @(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    @(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    @(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    @(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    @(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    @(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    @(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    @(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    @(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    @(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
)

This, of course, is completely un-scalable. From the first question, I found that $arr = @(0) * 10000 works for regular arrays, so I tried to use $array = @(@(0) * 10) * 10, and while this runs just fine, trying to access any element of this array gives me a 'Cannot modify because element is null' error.

To clarify, this code:

$array = @(
    @(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    @(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    @(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    @(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    @(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    @(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    @(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    @(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    @(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    @(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
)
Write-Host "$($null -eq $array[1][5])"

returns False, where as this code:

$array = @(@(0) * 10) * 10
Write-Host "$($null -eq $array[1][5])"

returns True.

What is the definitive, correct, scalable way to declare and initialize an array with N-dimensions?

4

1 Answer 1

1

What is the definitive, correct, scalable way to declare and initialize an array with N-dimensions?

$2DArray = [int[,]]::new(10,10)

This will create a 10x10 2D array that you can index into like this:

$null -ne $2DArray[1,5]

For a jagged array (an array of arrays), use the unary array operator ,:

$jaggedArray = ,((0) * 10) * 10 

This will create a 10-item array consisting of 10 10-item arrays of 0 that you can index into like this:

$null -ne $jaggedArray[1][5]

As mentioned in the comments, due to PowerShell's tendency to flatten any arrays, it might be better to devise a custom data type for collecting specific information:

using namespace System.Collections.Generic

class SensorSink {
  [List[int[]]]$Measurements = [List[int[]]]::new(10)

  AcceptTelemetry([int[]]$telemetry){
    if($telemetry.Count -ne 10){
      throw [ArgumentException]::new('telemetry', "Expected exactly 10 data points, received $($telemetry.Count)")
    }

    $this.Measurements.Add($telemetry)
  }
}
Sign up to request clarification or add additional context in comments.

4 Comments

This is all incredibly confusing for a Powershell newbie like me. Between regular and jagged arrays, hash tables, , vs @(). That said, your solution works perfectly. You really are a Powershell guru.
@martorad FWIW you almost never need nested arrays like this. Chances are whatever problem you're trying to solve, you'd probably be better off with an array of objects (custom or based of a class definition) describing the "inner" array values. But you'd have to tell us what you're actually trying to achieve with your 10x10 array if you what suggestions in that direction :)
I'm getting 10 values from 10 sensors on a microcontroller. I'm then receiving these values over Serial and reading them into my Powershell script. I receive these values 10 times, hence my 10x10 dimensionality. In truth, a regular array of 100 elements would absolutely suffice here, I decided to make it 2D purely because it looks nicer.
Final update, I first implemented the jaggedArray solution, which worked, but since I'm converting all my data to a JSON, it flattened it to 1 array of 100 elements. I then implemented the list of string arrays solution and that worked like a charm. Thank you!

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.