I have an int array in one dimension:
var intArray=new[] { 1, 2, 3, 4, 5, 6 };
and I want to convert it to two dimensions, such as:
var intArray2D=new[,] { {1, 2}, {3, 4}, {5, 6} };
How do I achieve this with C#?
with a loop perhaps:
for (int i = 0; i < oldArr.Length; i=i+2)
{
newArr[i/2, 0] = oldArr[i];
newArr[i/2, 1] = oldArr[i + 1];
}
Untested, but should get you pointed in the right direction...
If the one dimensional array contains the primitive data in row major order, and the total capacity of the 2 dimensional array equals the length of the one dimensional array, you can use this.
int[] source = new int[6];
int[,] target = new int[3, 2];
Buffer.BlockCopy(source, 0, target, 0, source.Length * sizeof(int));
Note that unlike Array.Copy and other array/list methods, Buffer.BlockCopy operates on a number of bytes of data, even if each element of the array is larger than 1 byte. It also only operates on arrays of primitive data types.
Additional references:
Multi-dimensional arrays are stored in row-major order (ECMA-335 Partition I, ยง8.9.1)
Buffer.BlockCopy
Edit: Here is a complete unit test.
[TestMethod]
public void SOTest16203210()
{
int[] source = new int[6] { 1, 2, 3, 4, 5, 6 };
int[,] destination = new int[3, 2];
Buffer.BlockCopy(source, 0, destination, 0, source.Length * sizeof(int));
Assert.AreEqual(destination[0, 0], 1);
Assert.AreEqual(destination[0, 1], 2);
Assert.AreEqual(destination[1, 0], 3);
Assert.AreEqual(destination[1, 1], 4);
Assert.AreEqual(destination[2, 0], 5);
Assert.AreEqual(destination[2, 1], 6);
}
I believe you want to split an integer array into an array of two integers each:
int[] list = new int[] { 1, 2, 3, 4, 5, 6};
int[][] newlist = new int[list.Length / 2][];
for (int i = 0, n = 0; i < list.Length; i += 2, n++)
{
newlist[n] = new[] { list[i], list[i + 1] };
}
To assign it to Points in particular you could try:
List<Point> plist = new List<Point>();
for (int i = 0; i < list.Length; i += 2)
{
plist.Add(new Point(list[i], list[i + 1]));
}
you may use this code. in here you can send any length you like. you can "deivde" the arry[] to arry[,] for any lenth.2 or 3 or what ever you like! as long as size % a.length ==0 !!!!
code
static int[,] convert(int[] a, int size)
{
int[,] value = new int[a.Length / size, size];
int counter = 0;
//
for (int b = 0; b < value.GetLength(0); b++)
for (int c = 0; c < value.GetLength(1); c++)
{
value[b, c] = a[counter];
counter++;
}
return value;
}
If the product of the dimensions are the same, the fastest way would probably be to pin the matrix using a fixed statement, then to use the Marshalling class to copy the continuous block from the array to an IntPtr created from the void* you got from the fixed.
You would have to wrap this in an unsafe statement and enable unsafe in the assembly's build config.
I have converted this from vb to c#
int Size = OldArray.Length;
int[,] NewPoints = null;
if (Size % 2 != 0) {
//Error - Array has odd number of elements!
} else {
for (i = 0; i <= Size - 1; i += 2) {
Array.Resize(ref AllPoints, (i / 2) + 1, 2);
NewPoints[i / 2, 0] = OldArray(i);
NewPoints[i / 2, 1] = OldArray(i + 1);
}
}
You could try this:
int [] a = {1,2,3,4,5,6};
int [,] b = new int[a.Length/2,2];
for(int i = 0;i<a.Length;i++)
{
b[i/2,i%2] = a[i];
}
Note that i/2 is an integer division, hence both 4/2 and 5/2 will give 2 which is a correct index in 2Darray for the tuple 5 and 6 from the original array. The second index is determined using reminder when divided by 2, it will give 0 if the index is even number and 1 if the index of the item from the original array is odd number.
I would consider this for any dimension of array:
public class TestClass {
public static void TestMethod2D() {
var intLinear=new[] { 1, 2, 3, 4, 5, 6 };
var indexer2D=new ArrayIndexer<int>(3, 2);
for(var i=intLinear.Length; i-->0; indexer2D[i]=intLinear[i])
;
var int2D=(int[,])indexer2D.ToArray();
}
public static void TestMethod4D() {
var intLinear=new[] { 1, 2, 3, 4, 5, 6 };
var indexer4D=new ArrayIndexer<int>(2, 2, 2, 2);
for(var i=intLinear.Length; i-->0; indexer4D[i]=intLinear[i])
;
var int4D=(int[, , ,])indexer4D.ToArray();
}
}
public partial class ArrayIndexer<T> {
public Array ToArray() {
return m_Array;
}
public ArrayIndexer(params int[] lengths) {
m_Array=Array.CreateInstance(typeof(T), lengths);
}
public T this[params int[] indices] {
set {
m_Array.SetValue(value, indices.Transform(m_Array));
}
get {
return (T)m_Array.GetValue(indices.Transform(m_Array));
}
}
Array m_Array;
}
public static partial class ArrayExtensions {
public static int[] Transform(
this int[] indices, Array array, bool isRowMajor=true) {
if(indices.Length>array.Rank)
return indices;
else {
var list=indices.ToList();
if(isRowMajor)
list.Reverse();
for(int r, q=0, i=0, count=array.Rank; count-->0; ++i) {
var index=isRowMajor?count-i:i;
if(indices.Length>i) {
q=Math.DivRem(indices[i]+q, array.GetLength(index), out r);
list[i]=r;
}
else {
if(index<0) {
list.Add(q);
q=0;
}
else {
q=Math.DivRem(q, array.GetLength(index), out r);
list.Add(r);
}
}
}
if(isRowMajor)
list.Reverse();
return list.ToArray();
}
}
}
ArrayExtensions.Transform is an indices transformer, it performs the linear transformation with the geometry of a given array. isRowMajor controls the layout, such as you would regard an int[,] in x, y or in y, x order.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
How can I make set complement and set difference in C# without using any collections and Linq?
We have two arrays:
int [] arr1 = new int { 1, 2, 3, 4};
int[] arr2 = new int {3,4,5,6,7,8};
Complement must be: arr3 {5,6,7,8} and the difference must be: arr4 {1,2}.
I've tried adding one set to another and then finding duplicates, but couldn't make it.
int numDups = 0, prevIndex = 0;
for (int i = 0; i < array.Length; i++)
{
bool foundDup = false;
for (int j = 0; j < i; j++)
{
if (array[i] == array[j])
{
foundDup = true;
numDups++; // Increment means Count for Duplicate found in array.
break;
}
}
if (foundDup == false)
{
array[prevIndex] = array[i];
prevIndex++;
}
}
// Just Duplicate records replce by zero.
for (int k = 1; k <= numDups; k++)
{
array[array.Length - k] = '\0';
}
You can create two lists, one for complement and other for difference, iterate array A and check which are contained in B and which not and vice-versa, iterate B and check which ones exists in A.
UPDATE: removed lists, used only arrays and no LINQ.
int[] arr1 = new int[]{ 1,2,3,4 };
int[] arr2 = new int[]{ 3,4,5,6,7,8 };
//We allocate the max possible size for each array, just for sanity
int[] arr3 = new int[arr1.Length + arr2.Length];
int[] arr4 = new int[arr1.Length + arr2.Length];
int difIndex = 0;
int compIndex = 0;
//Compute difference
foreach(int i in arr1)
{
bool found = false;
foreach(int i2 in arr2)
{
if(i == i2)
{
found = true;
break;
}
}
if(!found)
arr4[difIndex++] = i;
}
//Compute complement
foreach(int i in arr2)
{
bool found = false;
foreach(int i2 in arr1)
{
if(i == i2)
{
found = true;
break;
}
}
if(!found)
arr3[compIndex++] = i;
}
//Remove unused items from array
Array.Resize(ref arr3, compIndex);
Array.Resize(ref arr4, difIndex);
Given that premise, we could create the function getComplement like so:
int[][] getComplement(int[] arr1, int[] arr2) {
int[] complement = {};
int[] difference = {};
for (int i = 0; i < arr1.Length; i++)
{
bool isDupe = false;
for (int j = 0; j < arr2.Length; j++) {
if (arr1[i] == arr2[j] && !isDupe) {
Array.Resize(ref complement, complement.Length + 1);
complement[complement.GetUpperBound(0)] = arr2[j];
isDupe = true;
}
}
if (!isDupe) {
Array.Resize(ref difference, difference.Length + 1);
difference[difference.GetUpperBound(0)] = arr1[i];
}
}
return new[] { complement, difference };
}
and then apply it upon our 2 existing arrays to get the desired results:
int [] arr1 = new int[] { 1, 2, 3, 4 };
int[] arr2 = new int[] { 3, 4, 5, 6, 7, 8 };
int[][] complementArr = getComplement(arr1, arr2);
int[][] differenceArr = getComplement(arr2, complementArr[0]);
int[] arr3 = differenceArr[1];
int[] arr4 = complementArr[1];
You can see a working demo here.
The difference between collections A and B are all elements in A that are not in B. The compliment between those collections are all elements in B that are not in A. These are mirror definitions, so you really only need to write a method for difference and then have the compliment method call the difference method with the input parameters reversed.
(Well, strictly speaking, the compliment is all elements anywhere that are not in A, but that distinction is irrelevant here.)
// Get an array of all elements in b that are not in a
// This is identical to calling GetDifference with the inputs reversed so lets just do that
int[] GetCompliment(int[] a, int[] b) { return GetDifference(b, a); }
// Get an array of all elements in a that are not in b
int[] GetDifference(int[] a, int[] b)
{
// Create the buffer array at the worst-case length which is the length
// of a (where none of the elements in a are in b)
int[] c = new int[a.Length];
// Track how many elements we are actually ending up with
int length = 0;
// Loop through every element in a
foreach (var ax in a)
{
bool found = false;
// Loop through every element in b to see if it exists in a
foreach (var bx in b)
{
if (ax == bx)
{
// If the element was found in b, there's no reason to keep looping
found = true;
break;
}
}
// Only save the element if it was not found in b
if (!found)
{
c[length] = ax;
length++;
}
}
// Create the result array using the length of actual elements found
int[] result = new int[length];
// Copy the relevant slice of the buffer array into the result array
Array.Copy(c, result, length);
// Return the result array
return result;
}
Usage:
int[] a = { 1, 2, 3, 4 };
int[] b = { 3, 4, 5, 6, 7, 8 };
int[] c = GetDifference(a, b);
foreach(var cx in c)
{
Console.Write(cx + ", ");
}
Console.WriteLine();
int[] d = GetCompliment(a, b);
foreach(var dx in d)
{
Console.Write(dx + ", ");
}
// Output:
// 1, 2,
// 5, 6, 7, 8
DotNetFiddle
This is a basic question ( I am new to C#), but is there an efficient way to move the first element to the end of the array in C#?
I found this question, which describes the .rotate method in ruby, but I have been unable to find a similar method in C#.
If I have an array:
[1, 2, 3, 4, 5]
Is there a function in C# that returns:
[2, 3, 4, 5, 1]
Thanks in advance!
EDIT: Answer
The best solution is to use LinkedList<T> as many of you suggested and as shown in Alex's answer. His suggested solution was using:
list.AddLast(list.RemoveFirst());
which can be run in a for loop:
void func<T>(LinkedList<T> list, int rotate) {
for(var i = 0; i < rotate; i++) {
list.AddLast(list.RemoveFirst());
}
}
Thank you all for your help!
There are many ways to achieve this. One way would be:
var result = arr.Skip(1).Concat(arr.Take(1))
If you use LinkedList<T> instead of array<T> you could just use this:
list.AddLast(list.RemoveAndGetFirst());
Edit: RemoveAndGetFirst() can be an extension like:
LinkedListNode<T> elem = list.First;
list.RemoveFirst();
return elem;
Complexity O(1). When you perform this multiple times:
void func<T>(LinkedList<T> list, int rotate) {
for(var i = 0; i < rotate; i++) {
list.AddLast(list.RemoveFirst());
}
}
You will have a complexity of O(N) [where N is the number of rotations]. This is, performance wise, the best solution.
If you really need to use arrays this could be a naiv solution:
var tmp = list[0];
for(var i = 1; i < list.Length; i++) {
list[i - 1] = list[i];
}
list[list.Length - 1] = tmp;
(Be aware there are no range checks)
But this will be very time consuming if you need to do this often. If you perform this multiple times:
void func<T>(T[] list, int rotate) {
for(var j = 0; j < rotate; j++) {
var tmp = list[0];
for(var i = 1; i < list.Length; i++) {
list[i - 1] = list[i];
}
list[list.Length - 1] = tmp;
}
}
You will end up with O(N^2) = O(N * M) [where N is the number of elements and M the number of rotations]. This would be really bad. A better approach, if you know in advance you'll perform this often would be:
void func<T>(T[] list, int rotate {
for(var j = 0; j < list.Length; j++) {
var tmp = list[j];
var ix = (rotate + j) % list.Length;
list[j] = list[ix];
list[ix] = tmp;
}
}
Which will result in O(N) [where N is the number of elements].
As others already suggested, it's a good idea to write an extension method if you need this at multiple locations.
Using Array.Copy to copy elements to itself just shifted ;)
var array = new int[]{1, 2, 3, 4, 5};
var head = array[0];
Array.Copy(array, 1, array, 0, array.Length- 1);
array[array.Length - 1] = head;
And as an extension method returning a new array just like the Ruby version
static class ArrayRotateExtensions {
public static int[] Rotate(this int[] arr, int offset) {
var l = arr.Length;
var rot = new int[l];
if (offset == 0) {
Array.Copy(arr, 0, rot, 0, l);
return rot;
}
// constrain rotations greater than array length, it's the same result anyway
offset = offset % l;
// negative rotation is equal to positive rotation length - offset
if (offset < 0) {
offset += l;
}
Array.Copy(arr, offset, rot, 0, l - offset);
Array.Copy(arr, 0, rot, l - offset, offset);
return rot;
}
}
This will allow you to do
var array = new int[]{1, 2, 3, 4, 5};
var rotated = array.Rotate(1);
Plus rotation by any arbitrary amount.
Only downside is you'd have to add a version for every array type you'd like to use it on.
It's starting to look like Code Golf now :-) so here's my contribution:
var x = new[] { 1, 2, 3, 4, 5 };
var y = Enumerable.Range(1, x.Length).Select(i => x[i % x.Length]).ToArray();
The reason why there is no function like that in LINQ is most likely that people who developed LINQ didn't think it's something that is an absolute must...
If you really need that you can create an extension method.
Something along the lines of:
public static IEnumerable<T> Rotate<T>(this IEnumerable<T> elements, int number)
{
var elemetsList = elements as IList<T> ?? elements.ToList();
var list = new List<T>(elemetsList.Count);
if (number > elemetsList.Count - 1)
{
throw new ArgumentException(nameof(number));
}
for (int i = number; i < elemetsList.Count; i++)
{
list.Add(elemetsList[i]);
}
for (int i = 0; i < number; i++)
{
list.Add(elemetsList[i]);
}
return list;
}
And use it:
var arr = new int[] {1, 2, 3, 4, 5};
int[] result = arr.Rotate(1).ToArray();
int[] result2 = arr.Rotate(3).ToArray();
Output:
2 3 4 5 1
4 5 1 2 3
This solution is fairly efficient.
For an array 500 000 in length it took only 7ms on my machine to execute.
Try this one..
using System;
public class Program
{
public static int[] arrData = new int[5]{1,2,3,4,5};
public static void Main()
{
Console.WriteLine("\nOriginal array\n");
foreach(var item in arrData)
{
Console.WriteLine(item.ToString());
}
Console.WriteLine("\nShift to last\n");
arrData = shiftLast(arrData);
foreach(var item in arrData)
{
Console.WriteLine(item.ToString());
}
}
public static int[] shiftLast(int[] arr)
{
int last = arr[arr.Length - 1];
int first= arr[0];
arr[arr.Length - 1] = first;
arr[0] = last;
return arr;
}
}
Try to run here
Cheers
Maybe like this -
static void Main( string[] args ) {
Console.WriteLine(string.Join(", ", getArray(new int[] { 1, 2, 3, 4, 5 })));
Console.Read();
return;
}
static int[] getArray( int[] arr ) {
List<int> O = new List<int>();
for (int x = 1, l = arr.Length; x < l; x++) {
O.Add(arr[x]);
}
O.Add(arr[0]);
return O.ToArray();
}
As far as I know there isn't such method for an array. If you do this often perhaps you should consider using a different object (List<T>, Stack<T>, etc).
But even with an array you can implement simple functionality like this using extension methods:
public static int[] MoveFirstToLast (this int[] obj)
{
int movedValue = obj[0];
(int i = 1; i < obj.Length; i++)
{
obj[i - 1] = obj[i];
}
obj[obj.Length - 1] = movedValue;
return obj;
}
And then the use is just:
int[] myArray = //whatever;
int[] changedArray = myArray.MoveFirstToLast();
I need to sum the first and second, then the third and fourth then the fifth and sixth elements from an array.
For example if I get as input int[] {1, 2, 0, 3, 4, -1} I need to compute it to new int[] {3,3,3}
using System;
class Program
{
static void Main()
{
int[] Arr = new int[] {1, 2, 0, 3, 4, -1};
int sum = 0;
foreach(int index in Arr)
{
//sum = (Arr[index at 0 position] + Arr[item at 0 position + 1]);
//Then do nothing with Arr[index at 1 position]
//Then sum Arr[index at 2 position] + Arr[item at 3 position];
//Then do nothing with Arr[index at 4 position]
//if I test this condition
// if(Arr[index]%2==0) //here I want to test the actual index of the element, not the value behind the index
//{skip the next Arr[index]}
//else{ sum Arr[index]+Arr[index + 1] }
}
}
}
This Sums up each pair and leave the last as is if the length is odd:
int[] Arr = new int[] { 1, 2, 0, 3, 4 };
int ExactResultLength = (int)(((double)Arr.Length / 2) + 0.5);
int[] res = new int[ExactResultLength];
int j = 0;
for (int i = 0; i < Arr.Length; i+= 2)
{
if(i + 1 < Arr.Length)
res[j] = Arr[i] + Arr[i+1];
else
res[j] = Arr[i];
j++;
}
Assuming you don't care about an element left without a pair:
int[] Arr = new int[] {1, 2, 0, 3, 4, -1};
int[] Arr2 = new int[Arr.Length / 2];
for (int i = 0; i < Arr2.Length; i++)
Arr2[i] = Arr[i * 2] + Arr[i * 2 + 1];
But if you do and it should come in the output array, add the following row at the end:
Arr2[Arr2.Length - 1] = Arr[Arr.Length - 1];
and also change Arr2's length to Arr.Lenght / 2 + 1
I am converting 2dimensional array to Single dimensional in C#.
I receive the 2 dimensional array from device (C++) and then I convert it to 1 dimensional in C#.
Here is my code:
int iSize = Marshal.SizeOf(stTransactionLogInfo); //stTransactionLogInfo is a structure
byte[,] bData = (byte[,])objTransLog; //objTransLog is 2 dimensionl array from device
byte[] baData = new byte[iSize];
for (int i = 0; i < bData.GetLength(0); i++)
{
for (int j = 0; j < iSize; j++)
{
baData[j] = bData[i, j];
}
}
I get the desired result from above code, but the problem is it is not the standard way of implementation.
I want to know how it can be done in a standard way.
May be doing Marshalling , I am not sure.
Thanks in advance.
You can use the Buffer.BlockCopy Method:
byte[,] bData = (byte[,])objTransLog;
byte[] baData = new byte[bData.Length];
Buffer.BlockCopy(bData, 0, baData, 0, bData.Length);
Example:
byte[,] bData = new byte[4, 3]
{
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 },
{ 10, 11, 12 }
};
byte[] baData = new byte[bData.Length];
Buffer.BlockCopy(bData, 0, baData, 0, bData.Length);
// baData == { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }
Simplest method
int iSize = Marshal.SizeOf(stTransactionLogInfo); //stTransactionLogInfo is a structure
byte[,] bData = (byte[,])objTransLog; //objTransLog is 2 dimensionl array from device
byte[] baData = bData.Cast<byte>().ToArray();
bData.Cast<byte>() will convert the multi-dimensional array to a single dimension.
This will do boxing, unboxing so isn't the most performant way, but is certainly the simplest and safest.
If 2-D array's column size is dynamic, below code is usable:
public static T[] Convert2DArrayTo1D<T>(T[][] array2D)
{
List<T> lst = new List<T>();
foreach(T[] a in array2D)
{
lst.AddRange(a);
}
return lst.ToArray();
}
easy to understend and conver to a different language.
// Create 2D array (20 rows x 20 columns)
int row = 20;
int column = 20;
int [,] array2D = new int[row, column];
// paste into array2D by 20 elements
int x = 0; // row
int y = 0; // column
for (int i = 0; i < my1DArray.Length; ++i)
{
my2DArray[x, y] = my1DArray[i];
y++;
if (y == column)
{
y = 0; // reset column
x++; // next row
}
}
I want to create an n-dimensional array of doubles. At compile-time, the number of dimensions n is not known.
I ended up defining the array as a dictionary, with the key being an array of ints corresponding to the different axes (so in a 3-dimensional array, I'd supply [5, 2, 3] to get the double at (5, 2, 3) in the array.
However, I also need to populate the dictionary with doubles from (0, 0, ... 0) to (m1, m2, ... mn), where m1 to mn is the length of each axis.
My initial idea was to create nested for-loops, but as I still don't know how many I'd need (1 for each dimension), I can't do this at compile-time.
I hope I've formulated the question in an understandable manner, but feel free to ask me to elaborate parts.
To create a n-dimensional array, you can use the Array.CreateInstance method:
Array array = Array.CreateInstance(typeof(double), 5, 3, 2, 8, 7, 32));
array.SetValue(0.5d, 0, 0, 0, 0, 0, 0);
double val1 = (double)array.GetValue(0, 0, 0, 0, 0, 0);
array.SetValue(1.5d, 1, 2, 1, 6, 0, 30);
double val2 = (double)array.GetValue(1, 2, 1, 6, 0, 30);
To populate the arrays, you can use the Rank property and GetLength method to return the length of the current dimension, using a couple of nested for loops to do a O(n^m) algo (warning - untested):
private bool Increment(Array array, int[] idxs, int dim) {
if (dim >= array.Rank) return false;
if (++idxs[idxs.Length-dim-1] == array.GetLength(dim)) {
idxs[idxs.Length-dim-1] = 0;
return Increment(array, idxs, dim+1);
}
return true;
}
Array array = Array.CreateInstance(typeof(double), ...);
int[] idxs = new int[array.Rank];
while (Increment(array, idxs, 0)) {
array.SetValue(1d, idxs);
}
A quick followup on this matter:
We used the Array.CreateInstance method with success, but as someone predicted, it was fairly inefficient, and additionally created readability problems.
Instead, we have developed a method, where the n-dimensional array is converted into a 1-dimensional (normal) array.
public static int NDToOneD(int[] indices, int[] lengths)
{
int ID = 0;
for (int i = 0; i < indices.Length; i++)
{
int offset = 1;
for (int j = 0; j < i; j++)
{
offset *= lengths[j];
}
ID += indices[i] * offset;
}
return ID;
}
1DtoND(int[] indices, int[] arrayLengths)
{
int[] indices = new int[lengths.Length];
for (int i = lengths.Length - 1; i >= 0; i--)
{
int offset = 1;
for (int j = 0; j < i; j++)
{
offset *= lengths[j];
}
int remainder = ID % offset;
indices[i] = (ID - remainder) / offset;
ID = remainder;
}
return indices;
}
This is essentially a generalisation on the conversion of cartesian coordinates to a single integer and back again.
Our testing is not formalized, so any speedup we have gained is entirely anecdotal, but for my machine, it has given about a 30-50% speedup, depending on the sample size, and the readability of the code has improved by a wide margin.
Hope this helps anyone who stumbles upon this question.
Why don't you just use a multidimensional array: double[,,] array = new double[a,b,c]? All the array elements are automatically initialized to 0.0 for you.
Alternatively, you could use a jagged array double[][][], but each sub-array will need to be initialized in a for loop:
int a, b, c;
double[][][] array = new double[a][][];
for (int i=0; i<a; i++) {
double[i] = new double[b][];
for (int j=0; j<b; j++) {
double[i][j] = new double[c];
}
}
EDIT: didn't realise number of dimensions was run-time. Added another answer above.
With this method, you can create n-dimensional jagged arrays of any type.
public static Array CreateJaggedArray<T>(params int[] lengths)
{
if(lengths.Length < 1)
throw new ArgumentOutOfRangeException(nameof(lengths));
void Populate(Array array, int index)
{
for (int i = 0; i < array.Length; i++)
{
Array element = (Array)Activator.CreateInstance(array.GetType().GetElementType(), lengths[index]);
array.SetValue(element, i);
if (index + 1 < lengths.Length)
Populate(element, index + 1);
}
}
Type retType = typeof(T);
for (var i = 0; i < lengths.Length; i++)
retType = retType.MakeArrayType();
Array ret = (Array)Activator.CreateInstance(retType, lengths[0]);
if (lengths.Length > 1)
Populate(ret, 1);
return ret;
}