【问题标题】:3D array to 2D array - ignoring a dimension3D 数组到 2D 数组 - 忽略维度
【发布时间】:2017-01-28 11:18:40
【问题描述】:

我有一个非常大的 3D 数组,其中包含一些数据 - 2 x 10000 x 4000。我将处理其中一些数据,但我不需要知道第一个维度 (2)。

有没有一种简单的方法来获取我的 2 x 10000 x 4000 3D 数组并创建一个尺寸为 10000 x 4000 的 2D 数组?这可以在通过 for 循环的情况下完成吗?是否有一个复制功能或类似的东西可以让我将一个维度(或多个)的数组元素复制到一个全新的数组中?

【问题讨论】:

  • 只有当它是一个锯齿数组时:array[10000, 4000][2]
  • 不需要第一个维度是什么意思?您需要myArray[ 0, _, _ ]myArray[ 1 , _, _ ]。哪一个?
  • @InBetween - 基本上,我正在寻找一种使数组更小的方法。当我处理数据时,我不需要知道第一维中的值。
  • @InBetween 我将我的数据视为一个代表 3d 数组的巨大立方体。我有一个函数,它采用与第一个维度相对应的参数 - 0 或 1。我想采用该值并将立方体切片作为二维数组获取。我最终会将该 2d 数组作为 JSON 返回,这就是为什么我试图只返回我需要的数据,而不是整个 3d 数组。
  • 是的,这就是我的意思。问题是:你真的需要一个二维数组吗?或者你可以和可索引对象mySlicedArray[ i, j]一起生活吗?

标签: c# arrays for-loop multidimensional-array


【解决方案1】:

有办法,但我不会推荐它。这将使用不安全的指针进行复制。 (已测试)

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);

我看到你正在创建一个 json,这种方法在生成 json 时有点矫枉过正。不要对自己太苛刻。请改用循环。

【讨论】:

    【解决方案2】:

    我曾经为完整数组创建一个控制台命令,不知道它会如何用于锯齿状数组。

    你可以试试。

    代码sn-p:

    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]);
    

    【讨论】:

      【解决方案3】:

      如果您的操作是只读的,您可以使用函数参数选择维度。让你的数组是这样的:

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

      让你的操作员是这样的:

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

      如果您需要在其中写入,那么您就在正确的方式上使用数组的一部分的副本。在这种情况下,使用循环复制是没有办法的。

      如果您的数组有一些特殊的结构,您可以确定(例如,一半为零或类似于对称矩阵),您可以通过获取这些属性来节省一些迭代。

      【讨论】:

        【解决方案4】:

        实际上,我总是更喜欢一维数组。其他人的表现只是bad。 其他一切都可以通过数学来完成,您可以创建自己的类来轻松地在 3D、2D 甚至 1D 之间切换。

        这消除了你的问题,只需要一点额外的写作。

        【讨论】:

          猜你喜欢
          • 2019-08-20
          • 2016-03-25
          • 1970-01-01
          • 2012-12-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多