2次元配列をLINQ可能に
なるべく少ない手数でダメなソースを改善したいとき、急激にやる気を削がれるのが2次元配列だと思う。
コンストラクタで参照をコピーするので、メモリを2倍消費する事はないはず。(未検証)
使用時
var qArray = new Queryable2DimensionalArray<string>(昔の人が作った不便な2次元配列); //2カラム目が"B"の行だけ列挙する var result = qArray.Select((row) => row[2] == "B");
class定義
/// <summary> /// 2次元配列をジャグ配列の様な扱いにして、LINQを使って、片方の次元を1つずつ取り出せる様にする /// </summary> /// <remarks> /// 通常、2次元配列でforeachなどを使うと1次元的にアクセスしてしまうが、 /// これだと、ジャグ配列の様な取り出し方が出来る。 /// 2次元配列はLINQ出来ないが、出来るようになる。 /// </remarks> /// <typeparam name="T"></typeparam> class Queryable2DimensionalArray<T> : IEnumerable<T[]> { T[,] data; int dim0 = 0; int dim1 = 1; public Queryable2DimensionalArray(T[,] d) { data = d; } /// <summary> /// reverseがtrueの場合、0次元と1次元が入れ替わる /// </summary> /// <param name="d"></param> /// <param name="reverse"></param> public Queryable2DimensionalArray(T[,] d, bool reverse) { data = d; if (reverse) { dim0 = 1; dim1 = 0; } } public IEnumerator<T[]> GetEnumerator() { for (int i = 0; i < data.GetUpperBound(dim0) + 1; i++) { T[] result = new T[data.GetUpperBound(dim1) + 1]; for (int j = 0; j < data.GetUpperBound(dim1) + 1; j++) { result[j] = dim0 == 0 ? data[i, j] : data[j, i]; } yield return result; } } IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); } }
2015/11/05 ソース修正