2013-04-24 2 views
6

Ho un array int in una dimensione:Come convertire int [] a int [,] - C#

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

e voglio convertirlo in due dimensioni, come ad esempio:

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

Come ottengo ciò con C#?

+0

Cosa per '{1,2,3,4,5,6,8,9,10,11,12}'? '{{1,2,3,4}, {5,6,7,8}, {9,10,11,12}' o '{{1,2,3}, {4,5,6} , {7,8,9}, {10,11,12}} ' – I4V

+0

Avrai sempre una lunghezza uguale? La tupla sarà sempre una coppia? Controlla http://www.dotnetperls.com/tuple per vedere se questo ti aiuta a definire meglio la tua domanda. – AdamV

+1

Per un singolo array di colonne in un array a due colonne si presume, come indicato nella sua domanda. – Zeddy

risposta

1

credo si desidera dividere un array di interi in un array di due numeri interi ciascuno:

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

per assegnarlo a Points in particolare si potrebbe provare:

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

L'utilizzo di un array di matrici ([] []), quando la seconda dimensione è costante, è inefficiente rispetto a una matrice continua ([,]). –

+0

[Provalo.] (Https://code.google.com/p/proveit-js/) –

+1

Stai utilizzando una matrice di riferimenti agli array anziché a un grande array. Scrivi il tuo test per questo o apri un libro. –

2

con un ciclo, forse:

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

testato, ma dovrebbe farti puntato nella giusta direzione ...

+0

Solo i primi elementi nell'array ([0,1]) sono valori assegnati, ogni altro array ha il valore di 0s. – Syma

0

Se il prodotto delle dimensioni sono le stesse, il modo più veloce sarebbe probabilmente per bloccare la matrice usando un'istruzione fissa, quindi utilizzare la classe Marshalling per copiare il blocco continuo dall'array a un IntPtr creato dal vuoto * ottenuto dal fisso.

Si dovrebbe racchiudere questo in un'istruzione non sicura e abilitare non sicuro nella configurazione di build dell'assembly.

+1

Come questo ha qualcosa a che fare con la domanda? – Romoku

0

Si potrebbe provare questo:

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

noti che i/2 è una divisione di integer, quindi sia 4/2 e 5/2 darà 2 che è un indice corretto in 2Darray per tupla 5 e 6 dall'array originale. Il secondo indice viene determinato utilizzando il promemoria quando diviso per 2, fornirà 0 se l'indice è pari numero e 1 se l'indice dell'articolo dall'array originale è il numero dispari.

1

è possibile utilizzare questo codice. qui puoi inviare qualsiasi lunghezza che ti piace. puoi "deivde" l'arry [] per arry [,] per qualsiasi l.2.2 o 3 o qualunque cosa ti piaccia! purché la dimensione% a.length == 0 !!!!

codice

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

Ho convertito questo da VB a 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); 
    } 
} 
0

Vorrei considerare questo per qualsiasi dimensione di matrice:

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 è un trasformatore di indici, esegue la trasformazione lineare con la geometria di un determinato array. isRowMajor controlla il layout, ad esempio un int[,] in x, y o nell'ordine y, x.

+0

[La risposta di 280Z28] (http://stackoverflow.com/questions//how-to-convert-int-to-int-c-sharp/16204897#16204897) sembra migliore se il tipo di elemento è primitivo. –

2

Se la matrice monodimensionale contiene i dati primitivi in ​​row major order e la capacità totale dell'array bidimensionale è uguale alla lunghezza della matrice monodimensionale, è possibile utilizzarla.

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

noti che diversamente Array.Copy e altri metodi matrice/lista, Buffer.BlockCopy opera su un numero di byte di dati, anche se ogni elemento della matrice è maggiore di 1 byte. Funziona anche solo su matrici di tipi di dati primitivi.

Ulteriori riferimenti:

Edit: Ecco una prova di unità completa.

[TestMethod] 
public void SOTest() 
{ 
    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); 
} 
+0

Grazie per 'row-major'. –