6

私は1次元にint配列を持っています:

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

そして、次のような2次元に変換したい:

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

C#でこれを達成するにはどうすればよいですか?

4

8 に答える 8

2

1 次元配列にプリミティブ データが行優先順で含まれ、2 次元配列の合計容量が 1 次元配列の長さと等しい場合、これを使用できます。

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

Array.Copyおよび他の配列/リスト メソッドとは異なり、配列の各要素が 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);
}
于 2013-04-25T01:20:56.830 に答える
1

整数配列をそれぞれ2つの整数の配列に分割したいと思います:

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]));
}
于 2013-04-24T22:30:38.067 に答える
0

配列の任意の次元についてこれを検討します:

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はインデックス トランスフォーマーであり、指定された配列のジオメトリを使用して線形変換を実行します。inまたは in orderisRowMajorと見なすように、レイアウトを制御します。int[,]x, yy, x

于 2013-04-25T00:43:19.780 に答える
0

これを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);
  }
}
于 2013-04-24T22:41:42.157 に答える
0

これを試すことができます:

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 が得られます。これは、元の配列のタプル 5 と 6 に対する 2Darray の正しいインデックスです。2 番目のインデックスは、リマインダを使用して 2 で割ったときに決定されます。インデックスが偶数の場合は 0 になり、元の配列の項目のインデックスが奇数の場合は 1 になります。

于 2013-04-24T22:30:31.620 に答える