什么';s是从C#中的矩形数组中提取一维数组的最佳方法

本文关键字:数组 提取 一维数组 方法 最佳 是从 什么 | 更新日期: 2023-09-27 17:48:53

假设我有一个矩形字符串数组,而不是锯齿状数组

string[,] strings = new string[8, 3];

从中提取一维数组(单行或单列)的最佳方法是什么?当然,我可以用for循环来完成这项工作,但我希望.NET在.中有一种更优雅的方式

将提取的字符串数组转换为对象数组的奖励点数。

什么';s是从C#中的矩形数组中提取一维数组的最佳方法

您可以简单地将字符串数组强制转换为对象数组,否则是行不通的。不过,据我所见,实际的提取需要使用for循环: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方法并重用它们。

对于矩形阵列:

string[,] rectArray = new string[3,3] { 
    {"a", "b", "c"}, 
    {"d", "e", "f"}, 
    {"g", "h", "i"} };
var rectResult = rectArray.Cast<object>().ToArray();

对于锯齿状阵列:

string[][] jaggedArray =  { 
    new string[] {"a", "b", "c", "d"}, 
    new string[] {"e", "f"}, 
    new string[] {"g", "h", "i"} };
var jaggedResult = jaggedArray.SelectMany(s => s).Cast<object>().ToArray();

我只想澄清一下(给出了这个例子和所问的问题)。

锯齿状数组是数组的数组,声明如下:

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,00,1..等)寻址的,所以在这种情况下,您将无法使用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<object>().ToArray();
}
static object[] GetRow(string[][] source, int row) {
    return source.Skip(row).First().Cast<object>().ToArray();
}
public class Pair<T> {
    public int Index;
    public T Value;
    public Pair(int i, T v) {
        Index = i;
        Value = v;
    }
}
static IEnumerable<Pair<T>> Iterate<T>(this IEnumerable<T> source) {
    int index = 0;
    foreach (var cur in source) {
        yield return new Pair<T>(index, cur);
        index++;
    }
}

使用Array可以轻松复制行。复制:

        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) ;