2016-07-19 10 views
0

私は問題に遭遇しました。何かが欠けているのか、それともC#で本当に厄介なのか分かりません。2D配列のマッピング

私は2D配列(Foo[,])を持っています。私がしたいのは、以外のものを使用してBar[,]にマップすることです。基本的に、私が欲しいのは、与えられたTに対して、T[,]のファンクタインスタンスです。

"明白な"方法はもちろん、新しい列を最初から構築し、各列の行と列を繰り返し、手動で関数をセルに適用することです。これは

from cell in matrix 
select f(cell) 

または同等matrix.Select(f)よりも複雑である必要があり全く理由がないので、私は本当に、このかかわらずのためにLINQを使用するようにしたいと思います。

私はこれをやりたい最初の人にはなれないと思うので、似たようなものがあるのだろうか、それとも自分のLINQ拡張機能を2次元配列?

答えて

0

2d配列で直接動作する.NET FrameworkにはLINQメソッドはありません。解決策として

マニュアルCastWhy do C# Multidimensional arrays not implement IEnumerable<T>?Using Linq with 2D array, Select not found)と非ジェネリックIEnumerableを経由してすべての項目を反復処理 - - あなたは、組み込みのコードから得ることができる最高のは、独自の拡張機能を書いたり、ライブラリを見つけます。

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