矩阵到数组c#
本文关键字:数组 | 更新日期: 2023-09-27 18:21:16
转换这样的平方矩阵的最有效方法
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]);
}
}
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;
}
正如Jeff所说,LINQ让这件事变得微不足道。OfType<>()
通常应该比Cast<>
快一点,不过:
array1D = array2D.OfType<int>().ToArray();
然而,正如@phoog所提到的,OfType<>
的实现仍将受到装箱/取消装箱处罚。
只是为了好玩,如果你想要一个快速的基于LINQ的解决方案(避免装箱的成本),你可以使用这个小的扩展方法:
static class LinqEx
{
public static IEnumerable<T> Flatten<T>(this T[,] matrix)
{
foreach (var item in matrix) yield return item;
}
}
或者这个,基于Jeff的第二个解决方案:
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();
我没有完全介绍这一点,但我希望这将比基于LINQ/IEnumerable的内置选项获得更好的性能。然而,杰夫的第二个解决方案似乎总是禁食。
使用Buffer.BlockCopy:的替代解决方案
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));
您最好一次性分配完整的结果数组,然后将数据复制到.中
你应该找到这样的总尺寸;
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的memcpy函数来进行低级别的块复制。这是尽可能高效的。