在C#中从矩形数组中提取一维数组的最佳方法是什么?
假设我有一个矩形字符串数组 – 不是锯齿状数组
string[,] strings = new string[8, 3];
从中提取一维数组(单行还是单列)的最佳方法是什么? 当然,我可以使用for循环执行此操作,但我希望.NET内置更优雅的方式。
用于将提取的字符串数组转换为对象数组的加值点。
对于矩形arrays:
string[,] rectArray = new string[3,3] { {"a", "b", "c"}, {"d", "e", "f"}, {"g", "h", "i"} }; var rectResult = rectArray.Cast
对于锯齿状arrays:
string[][] jaggedArray = { new string[] {"a", "b", "c", "d"}, new string[] {"e", "f"}, new string[] {"g", "h", "i"} }; var jaggedResult = jaggedArray.SelectMany(s => s).Cast
你可以简单地将一个字符串数组转换为一个对象数组 – 另一种方式不起作用。 实际的提取必须使用for循环,据我Array.Copy
: Array.Copy
要求源和目标等级相同,而Buffer.BlockCopy
仅适用于值类型数组。 虽然看起来很奇怪……
您可以在单个语句中使用LINQ来添加行或列,尽管它效率低(因为它会在内部构建列表,然后必须将其转换为数组 – 如果您自己执行,则可以预先分配数组大小合适并直接复制)。
复制行( rowNum
是要复制的行):
object[] row = Enumerable.Range(0, rowLength) .Select(colNum => (object) stringArray[rowNum, colNum]) .ToArray();
复制列( colNum
是要复制的列):
object[] column = Enumerable.Range(0, columnLength) .Select(rowNum => (object) stringArray[rowNum, colNum]) .ToArray();
我不确定这是否比foreach循环更好/更简单 – 特别是如果你编写ExtractRow
方法和ExtractColumn
方法ExtractRow
用它们。
我想澄清一下(给出例子以及被问到的内容)。
锯齿状数组是一个数组数组,声明如下:
string[][] data = new string[3][]; data[0] = new string[] { "0,[0]", "0,[1]", "0,[2]" }; data[1] = new string[] { "1,[0]", "1,[1]", "1,[2]" ]; data[2] = new string[] { "2,[0]", "1,[1]", "1,[2]" };
与矩形数组相对应 ,定义为包含多个维度的单个数组:
string[,] data = new string[3,3]; data[0,0] = "0,0"; data[0,1] = "0,1"; data[0,2] = "0,2"; ...etc
因此, 锯齿状数组是IQueryable / IEnumerable,因为您可以迭代它以在每次迭代时接收数组。 而矩形数组 不是 IQueryable / IEnumerable,因为元素以完整维度(0,0 0,1..etc)进行寻址,因此在这种情况下,您将无法使用Linq或为Array创建的任何预定义函数。
虽然你可以迭代一次数组(并实现你想要的),如下所示:
/// INPUT: rowIndex, OUTPUT: An object[] of data for that row int colLength = stringArray.GetLength(1); object[] rowData = new object[colLength]; for (int col = 0; col < colLength; col++) { rowData[col] = stringArray[rowIndex, col] as object; } return rowData; /// INPUT: colIndex, OUTPUT: An object[] of data for that column int rowLength = stringArray.GetLength(0); object[] colData = new object[rowLength]; for (int row = 0; r < rowLength; row++) { colData[row] = stringArray[row, colIndex] as object; } return colData;
希望这可以帮助 :)
LINQ就是答案
static object[] GetColumn(string[][] source, int col) { return source.Iterate().Select(x => source[x.Index][col]).Cast
可以使用Array.Copy轻松复制行:
int[][] arDouble = new int[2][]; arDouble[0] = new int[2]; arDouble[1] = new int[2]; arDouble[0][0] = 1; arDouble[0][1] = 2; arDouble[1][0] = 3; arDouble[1][1] = 4; int[] arSingle = new int[arDouble[0].Length]; Array.Copy(arDouble[0], arSingle, arDouble[0].Length);
这会将第一行复制到单个Dimension数组中。
我做了扩展方法。 我不知道性能。
public static class ExtensionMethods { public static string[] get1Dim(this string[,] RectArr, int _1DimIndex , int _2DimIndex ) { string[] temp = new string[RectArr.GetLength(1)]; if (_2DimIndex == -1) { for (int i = 0; i < RectArr.GetLength(1); i++) { temp[i] = RectArr[_1DimIndex, i]; } } else { for (int i = 0; i < RectArr.GetLength(0); i++) { temp[i] = RectArr[ i , _2DimIndex]; } } return temp; } }
用法
// we now have this funtionaliy RectArray[1, * ] // -1 means ALL string[] _1stRow = RectArray.get1Dim( 0, -1) ; string[] _2ndRow = RectArray.get1Dim( 1, -1) ; string[] _1stCol = RectArray.get1Dim( -1, 0) ; string[] _2ndCol = RectArray.get1Dim( -1, 1) ;