如何将int[]转换为int[,] - c#

本文关键字:int 转换 | 更新日期: 2023-09-27 18:10:58

我有一个一维的int数组:

var intArray=new[] { 1, 2, 3, 4, 5, 6 };

,我想把它转换成二维,比如:

var intArray2D=new[,] { {1, 2}, {3, 4}, {5, 6} };

我如何用c#实现这一点?

如何将int[]转换为int[,] - c#

与一个循环也许:

for (int i = 0; i < oldArr.Length; i=i+2)
{
    newArr[i/2, 0] = oldArr[i];
    newArr[i/2, 1] = oldArr[i + 1];
}

未经测试,但应该会让你指向正确的方向…

如果一维数组包含按行主序排列的原始数据,并且二维数组的总容量等于一维数组的长度,则可以使用

int[] source = new int[6];
int[,] target = new int[3, 2];
Buffer.BlockCopy(source, 0, target, 0, source.Length * sizeof(int));

注意,与Array.Copy和其他数组/列表方法不同,Buffer.BlockCopy字节的数据进行操作,即使数组的每个元素都大于1字节。它也只能操作基本数据类型的数组。

额外的引用:

  • 多维数组按行主序存储(ECMA-335 Partition I,§8.9.1)
  • Buffer.BlockCopy
编辑:这是一个完整的单元测试。
[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);
}

我相信你想把一个整数数组分成两个整数数组:

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

要将它特别分配给Points,您可以尝试:

List<Point> plist = new List<Point>();
for (int i = 0; i < list.Length; i += 2)
{
    plist.Add(new Point(list[i], list[i + 1]));
}

您可以使用此代码。在这里你可以发送任何你喜欢的长度。您可以将array[]"分割"为任意长度的array[,]。2个或3个,随便你!只要size % a.length ==0 !!!!

代码
        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;
    }

如果维度的乘积是相同的,最快的方法可能是使用固定语句固定矩阵,然后使用Marshalling类将连续块从数组复制到一个IntPtr中,该IntPtr是从固定的void*中创建的。

您必须将其封装在不安全语句中,并在程序集的构建配置中启用不安全。

我已经把它从vb转换为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);
  }
}

你可以试试:

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

请注意,i/2是一个整数除法,因此4/2和5/2都将给出2,这是2array中原始数组中元组5和6的正确索引。第二个索引是在除以2时使用提醒确定的,如果索引是偶数,则返回0,如果原始数组中的项的索引是奇数,则返回1。

对于数组的任何维度,我都会考虑这样做:

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是一个索引转换器,它对给定数组的几何形状进行线性变换。isRowMajor控制布局,就像x, yy, x顺序中的int[,]一样。