2012-01-25 61 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));