2

I have a very large 3D array containing some data - 2 x 10000 x 4000. I'm going to be processing some of this data but I don't need to know about the first dimension (2).

Is there a simple way to take my 2 x 10000 x 4000 3D array and create a 2D array with the dimensions 10000 x 4000? Can this be done without going through a for loop? Is there a copy function or something similar that allows me to copy over an arrays elements for a single dimension (or multiple) into a brand new array?

Roka545
  • 3,404
  • 20
  • 62
  • 106
  • 1
    Only if it is a jagged array: `array[10000, 4000][2]` – D Stanley Sep 20 '16 at 14:13
  • What does it mean that you don't need the first dimension? You either need `myArray[ 0, _, _ ]` or `myArray[ 1 , _, _ ]`. Which one? – InBetween Sep 20 '16 at 14:26
  • @InBetween - Basically, I'm looking for a way to make the array smaller. When I process the data I don't need to know about the values in the first dimension. – Roka545 Sep 20 '16 at 14:30
  • @InBetween I'm looking at my data as one huge cube representing the 3d array. I have a function that takes a parameter that corresponds to the first dimension - 0 or 1. I want to take that value and grab the cube slice as a 2d array. I'll eventually return that 2d array as JSON, which is why I'm trying to only return the data I need, and not the entire 3d array. – Roka545 Sep 20 '16 at 14:33
  • Yeah, thats what I meant. The question is: do you really need a 2D array? Or can you live with and indexable object `mySlicedArray[ i, j]`? – InBetween Sep 20 '16 at 14:47
  • Without using loops? No. If you just want one big array you would have to initialize it with the new total based upon the jagged array and then loop though it and set the indices. – Krythic Sep 20 '16 at 15:07
  • Actually i would always prefer a single dimension array. The performance of the others are just [bad](https://stackoverflow.com/questions/468832/why-are-multi-dimensional-arrays-in-net-slower-than-normal-arrays). Everything else can be done with mathmatics and you can create your own classes to switch easy between 3D, 2D or even 1D. This removes the problem you have and requires only a little bit of extra writing. – Felix K. Sep 20 '16 at 14:54

3 Answers3

2

There is a way, but I won't recomment it. This will copy using unsafe pointers. (tested)

int[,,] myArray = new int[2, 1000, 400];
int[,] myArray2 = new int[1000, 400];

var i = myArray.GetLength(1);
var j = myArray.GetLength(2);
var pageIndex = 0;

unsafe
{
    fixed (void* source = &myArray[pageIndex, 0, 0])
    fixed (void* dest = &myArray2[0, 0])
    {
        CopyMemory((IntPtr)dest, (IntPtr)source, (uint)(i*j*sizeof(int)));
    }
}


[DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);

I see that you're creating a json, this method is way overkill when generating json. Don't make it too hard on yourself. Use a loop instead.

Jeroen van Langen
  • 21,446
  • 3
  • 42
  • 57
0

I used to create a console command for full arrays, No idea how it will turn out for jagged arrays.

You can try though.

Code snippet:

float[,] f = new float[3,3] { {1, 2, 3},
                              {4, 5, 6},
                              {7, 8, 9}  };
float[,] g = new float[3,3];

Array.Copy(f, 0, g, 0, f.Length); 


Console.WriteLine("{0} {1} {2}", f[0, 0], f[0, 1], f[0, 2]);
Console.WriteLine("{0} {1} {2}", f[1, 0], f[1, 1], f[1, 2]);
Console.WriteLine("{0} {1} {2}", f[2, 0], f[2, 1], f[2, 2]);
Console.WriteLine();
Console.WriteLine("{0} {1} {2}", g[0, 0], g[0, 1], g[0, 2]);
Console.WriteLine("{0} {1} {2}", g[1, 0], g[1, 1], g[1, 2]);
Console.WriteLine("{0} {1} {2}", g[2, 0], g[2, 1], g[2, 2]);
Barr J
  • 10,636
  • 1
  • 28
  • 46
0

If your operation is read-only, you could select the dimension using a function argument. Let your array be like this:

float[,,] f = new float[2,10000,4000];

Let your operator be like this:

void myOperation(float[,,] pArray, int p1stDimensionSelector) {
  for (int i = ...; i < ...; i++) {
    for (int j = ...; j < ...; j++) {
      // do fancy stuff with pArray[p1stDimensionSelector, i, j]
    }
  }
}

If you need to write in it, you are on the right way with a copy of a part of the array. In this case there is no way out of copying with loops.

If your array has some special structure, that you can be sure of (like, half of it is zero or it resembles a symmetric matrix) you could save some iterations by seizing these properties.

Chris Tophski
  • 930
  • 1
  • 6
  • 23