简体   繁体   中英

get partition ((N-1)-dimensional instance of the N-dimensional array) of a multidimensional array with LINQ

I want to get a 2d array from a 3d array. Let's say I have a double 3d array A3 of dimension [10,10,10]
I need to get a 2d array A2 = A3[:,5,:], ie where the index of the second dimension is equal to eg 5.

If I want to get the partition (for instance of the kind A1=A2[2,:]) of 2d array A2 (ie 1d instance of 2d array) I can do this (the index of the 1-st dimensional is set eg to 2):

double[] A1 = Enumerable.Range(0,A2.Length).Select(x=>A2[2,x]).ToArray();

How can I do it going from 3 to 2 (or generally from N to N-1) dimensions?

Edit . Example input:

double[,,] A3 = new double[2,3,4]{
            {
                {4,3,2,1},
                {5,4,3,2},
                {6,5,4,3}
            },
            {
                {1,2,3,4},
                {2,3,4,5},
                {3,4,5,6}
            }
        };

The result array A2=A3[:,1,:] must have the following inside: { {5,4,3,2},{2,3,4,5} }

LINQ in general doesn't play too well with multi-dimensional arrays. The operations are inherently single dimensional. It plays much better with nested single dimensional arrays, so if you wanted to return a jagged array of depth two, ie a double[][] rather than a double[,] LINQ is a more appropriate tool.

public static T[][] GetPlane<T>(T[, ,] source, int secondDimensionValue)
{
    return Enumerable.Range(0, source.GetLength(0))
        .Select(i => Enumerable.Range(0, source.GetLength(2))
            .Select(j => source[i, secondDimensionValue, j])
            .ToArray())
        .ToArray();
}

Something like this should work for 3->2:

static T[][] Collapse<T>(T[][][] array, int y)
{
  return
    Enumerable.Range(0, array.Length).Select(x =>
      Enumerable.Range(0, array[x][y].Length).Select(z =>
        array[x][y][z]
      ).ToArray()
   ).ToArray();
}

It should be fairly obvious how to extend this pattern to higher dimensional problems.

Edit:

This extends to multidimensional arrays in the expected manner. If you're interested in returning a multidimensional array (as opposed to a jagged array), LINQ probably isn't the tool that you want to use to solve this problem as it provides no obvious or intuitive methods for handling multidimensional array creation.

If you really want the multidimensional array as output, I've included a sample "deburr" implementation that should collapse it back to a multidimensional (non-jagged) array.

static T[][] Collapse<T>(T[,,] array, int y)
{
  return
    Enumerable.Range(0, array.GetLength(0)).Select(x =>
      Enumerable.Range(0, array.GetLength(2)).Select(z =>
        array[x,y,z]
      ).ToArray()
    ).ToArray();
}

static T[,] Deburr<T>(T[][] jagged)
{
  T[,] mArray = new T[jagged.Length, jagged.Max(array => array.Length)];

  foreach (int row in Enumerable.Range(0, jagged.Length))
    foreach (int col in Enumerable.Range(0, jagged[row].Length))
      mArray[row, col] = jagged[row][col];

  return mArray;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM