2016-07-19 89 views
0

我遇到了一個問題,我不確定我是否錯過了某些東西,或者它在C#中真的很笨重。通過二維數組映射

我有一個二維數組(Foo[,]),我想要做的就是把它映射到一個Bar[,],使用只是一個Func<Foo, Bar>。基本上,我想要的是對於任何給定的TT[,]的仿函數實例。

「顯而易見」的方式當然是從頭開始構建一個新的數組,遍歷每一列的行和列並手動將該函數應用於任何單元格。我真的想使用LINQ的針對這一點,因爲沒有任何理由,這應該是比

from cell in matrix 
select f(cell) 

或等值matrix.Select(f)更加複雜。

我不禁想到,我不能成爲第一個想做這件事的人,所以我想知道是否有類似的內置內容,或者我最好只寫自己的LINQ擴展二維數組?

回答

0

.Net Framework中沒有LINQ方法直接與2d數組一起工作。通過非通用IEnumerable帶手動CastWhy do C# Multidimensional arrays not implement IEnumerable<T>?Using Linq with 2D array, Select not found)遍歷所有項目

作爲解決方案 - - 你可以從內置的代碼中得到的最編寫自己的擴展或查找圖書館。

+0

寫一堆自定義的LINQ擴展看起來是最簡單和最乾淨的路徑。這種繁瑣的編寫和維護這種樣板代碼,但哦。 – kai

0

不知道這是否是「最好」的方式(無論這意味着什麼),但這至少起作用。如果您需要更多的LINQ語法,可以輕鬆擴展。

public static class Matrix 
{ 
    public static TResult[,] Select<T, TResult>(this T[,] source, Func<T, TResult> f) 
    { 
     var rows = source.GetLength(0); 
     var columns = source.GetLength(1); 
     var result = new TResult[rows, columns]; 

     for (var row = 0; row < rows; row++) 
     { 
      for (var column = 0; column < columns; column++) 
      { 
       result[row, column] = f(source[row, column]); 
      } 
     } 

     return result; 
    } 
} 

使用以下(相當缺乏光澤)xunit實際測試,隨意指出錯誤。

[Fact] 
public void MatrixSelect_GivenFunction_MapsMatrix() 
{ 
    var matrix = new[,] 
    { 
     {true, true}, 
     {false, true} 
    }; 

    var transformed = 
     from cell in matrix 
     select cell ? 1 : 0; 

    var expected = new[,] 
    { 
     {1, 1}, 
     {0, 1} 
    }; 
    Assert.Equal(expected, transformed); 
}