簡體   English   中英

在C#中從矩形數組中提取一維數組的最佳方法是什么?

[英]What's the best way to extract a one-dimensional array from a rectangular array in C#?

假設我有一個矩形字符串數組 - 不是鋸齒狀數組

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

從中提取一維數組(單行還是單列)的最佳方法是什么? 當然,我可以使用for循環執行此操作,但我希望.NET內置更優雅的方式。

用於將提取的字符串數組轉換為對象數組的加值點。

您可以簡單地將字符串數組轉換為對象數組 - 另一種方式不起作用。 實際的提取必須使用for循環,據我Array.CopyArray.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[,] 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,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<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.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) ; 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM