2012-01-25 221 views
3

這將是最有效的方式像矩陣陣列C#

1 2 3 
    4 5 6 
    7 8 9 

方形矩陣轉換成

[1 2 3 4 5 6 7 8 9] 

在C#

我是做

int[,] array2D = new int[,] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }; 
int[] array1D = new int[9]; 
int ci=0; 

for (int i = 0; i < 3; i++) 
{ 
     for (int j = 0; j < 3; j++) 
     { 
      array1D[ci++] = array2D[i, j]); 
     } 
} 
+2

[本] [1]似乎是同樣的問題,回答。 [1]:http://stackoverflow.com/questions/2569279/how-to-flatten-2d-array-to-1d-array – Oleksi

+1

@Olexsi它不是完全一樣;這個問題使用了一個適當的二維數組,而你鏈接的是詢問一個二維鋸齒狀數組。 – phoog

回答

0

你總是最好分配完整的結果陣列中的一重擊,然後在複製數據

你應該找到這樣的總規模。

var size = arrays.Sum(a=> a.Length); 
var result = new int[size]; 

然後使用Array.CopyTo複製數組,而不是循環自己;

var cursor = 0; 
foreach(var a in arrays) { 
    a.CopyTo(result, cursor); 
    cursor += a.Length;  
} 

Array.CopyTo將比你自己的循環更快;至少,不會更慢。它可能會在內部使用C's memcpy函數來執行低級別塊複製。這是一樣有效的,你可以。使用Buffer.BlockCopy

7

LINQ使這個微不足道。

int[,] array2d = ...; 
var array1d = array2d.Cast<int>().ToArray(); 

否則,你的方法是足夠的,但可以推廣:

int[,] array2d = ...; 
var rows = array2d.GetLength(0); 
var cols = array2d.GetLength(1); 
var array1d = new int[rows * cols]; 
var current = 0; 
for (int i = 0; i < rows; i++) 
{ 
    for (int j = 0; j < cols; j++) 
    { 
     array1d[current++] = array2d[i, j]; 
    } 
} 

甚至:

int[,] array2d = ...; 
var array1d = new int[array2d.GetLength(0) * array2d.GetLength(1)]; 
var current = 0; 
foreach (var value in array2d) 
{ 
    array1d[current++] = value; 
} 
+0

哪一個更快更省資源? – kbvishnu

+0

我不知道,我自己沒有對它進行簡介。但我懷疑第三個版本會是最快的。 –

+0

什麼是abt LINQ?它會很快,我希望 – kbvishnu

1

正如傑夫說,LINQ使這微不足道的。 OfType<>()一般應該是快一點比Cast<>雖然:

array1D = array2D.OfType<int>().ToArray(); 

OfType<>實施但仍然會從拳擊/拆箱處罰受到影響,@phoog提及。

只是爲了好玩,如果你想有一個快速的基於LINQ的解決方案(避免拳擊的費用),你可以用這個小的擴展方法:

static class LinqEx 
{ 
    public static IEnumerable<T> Flatten<T>(this T[,] matrix) 
    { 
     foreach (var item in matrix) yield return item; 
    } 
} 

或者這個的基礎上,傑夫的第2個解決方案:

public static IEnumerable<T> Flatten<T>(this T[,] matrix) 
    { 
     var rows = matrix.GetLength(0); 
     var cols = matrix.GetLength(1); 
     for (var i = 0; i < rows;i++) 
     { 
      for (var j = 0; j < cols; j++) 
       yield return matrix[i, j]; 
     } 
    } 

用法:

int[,] array2D = new int[,] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }; 
int[] array1D = array2D.Flatten().ToArray(); 

我沒有完全資料這個,但我希望這WIL我比基於LINQ/IEnumerable的內置選項獲得更好的性能。看起來,傑夫的第二個解決方案總是禁食。

1

替代解決方案:

int[,] array2D = new int[,] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }; 
int[] array1D = new int[ array2D.Length ]; 
Buffer.BlockCopy(array2D, 0, array1D, 0, array1D.Length * sizeof(int));