How to create an Array of varying dimensions? (jagged array)

for example

an array of doubles

double[] myArr;

if i was to create an array of arrays it would be

double[][] myArr;

an array of array of arrays

double[][][] myArr;

how would i set this so i can have n number of arrays of arrays without having to define them all (just have 1 that can be on n number of arrays/ dimentions)

example (extreme case)

double[][][][][][][][][][][] myArr;

You could probably create object tree instead, which contains more object of the same kind, primitive array of list depending of needs for scale. Initialization could happen recursively.

ok the best way i’ve found is to use a single dimension array and extend its size. Will post the loop later as it’s a bit tricky unless someone figures it out and posts it in a format like this

0,0,{0,1,2,3,4}  0,1,{0,1,2,3,4}  0,2,{0,1,2,3,4}  
0,0,{0,1,2,3,4}  0,1,{0,1,2,3,4}  0,2,{0,1,2,3,4}  
0,0,{0,1,2,3,4}  0,1,{0,1,2,3,4}  0,2,{0,1,2,3,4}  

1,0,{0,1,2,3,4}  1,1,{0,1,2,3,4}  1,2,{0,1,2,3,4}  
1,0,{0,1,2,3,4}  1,1,{0,1,2,3,4}  1,2,{0,1,2,3,4}  
1,0,{0,1,2,3,4}  1,1,{0,1,2,3,4}  1,2,{0,1,2,3,4}  

 int[] lengthsOfEachDimentions = { 2, 3, 5 };
 // size = 30 , 2*3*5
 int size = lengthsOfEachDimentions.Aggregate ((a,b) => a*b);
 double[] myArr = new double;

This cannot be done at compile time, you have to create a custom tree-like structure and initialize it at runtime. I made an evil example that does the trick:

    using System;

    public abstract class Hyperarray {
        public abstract double Get(int[] coords, int dimension = 0);
        public abstract void Set(int[] coords, double data, int dimension = 0);
    }

    public class Node : Hyperarray {
        private Hyperarray[] children;

        public void SetChildren(Hyperarray[] children) {
            this.children = children;
        }

        public override double Get(int[] coords, int dimension = 0) {
            if (dimension < coords.Length && coords[dimension] < children.Length) {
                Hyperarray node = children[coords[dimension]];
                return node.Get(coords, dimension + 1);
            } else
                throw new ArgumentException("Wrong hyperarray coordinates !");
        }

        public override void Set(int[] coords, double data, int dimension = 0) {
            if (dimension < coords.Length && coords[dimension] < children.Length) {
                Hyperarray node = children[coords[dimension]];
                node.Set(coords, data, dimension + 1);
            } else
                throw new ArgumentException("Wrong hyperarray coordinates !");
        }        
    }

    public class Leaf : Hyperarray {
        private double data;

        public override double Get(int[] coords, int dimension = 0) {
            if (dimension == coords.Length)
                return data;
            else
                throw new ArgumentException("Wrong hyperarray coordinates !");
        }
        public override void Set(int[] coords, double data, int dimension = 0) {
            if (dimension == coords.Length)
                this.data = data;
            else
                throw new ArgumentException("Wrong hyperarray coordinates !");
        }
    }

Use this method to initialize the array based on the dimensions you provide:

    Hyperarray Create(int[] dimensions, int index = 0) {
        if (index < dimensions.Length && dimensions[index] > 0) {
            Node array = new Node();
            Hyperarray[] children = new Hyperarray[dimensions[index]];
            for (int i = 0; i < dimensions[index]; ++i)
                children *= Create(dimensions, index + 1);*

array.SetChildren(children);
return array;
} else if (index == dimensions.Length)
return new Leaf();
else
throw new ArgumentException(“Wrong hyperarray create parameters !”);
}
And finally here is an example of usage:
int[] dim = { 2, 4, 5, 3, 3 };
Hyperarray array = Create(dim, 0);
int[] coords = { 1, 0, 3, 4, 1 };
node.Set(coords, 3.14d);
double data = node.Get(coords);
print(data);
I tested it a bit and it should work fine. Note that I did not cover all special cases of wrong usage, I am definitely not satisfied with the overall design, encapsulation, default-value parameters in the methods, etc, etc. I primarily made it for fun and because it was interesting.
Also be careful with the number of dimension you provide, the size of the structure grows exponentially in the memory !
Oh yeah and the last thing, for the love of god don’t use it at all since this thing will give the garbage collector extremely violent and eternal nightmares. I can’t even think of a reasonable scenario where it cannot be substituted by something more efficient and intelligent. I strongly suggest you do some research and preferably use some hash set, or dictionary with string keys, or something like that…