概要
テーブルのような2次元のListがあるとします。
new List<List<string>>()
{
new List<string>() {"1a", "1b", "1c"},
new List<string>() {"2a", "2b", "2c"},
new List<string>() {"3a", "3b", "3c"}
}
下記のように横のListが縦に並び変わるようなメソッドを作成していきます。
// 変換後
new List<List<string>>()
{
new List<string>() {"1a", "2a", "3a"},
new List<string>() {"1b", "2b", "3b"},
new List<string>() {"1c", "2c", "3c"}
}
図にすると下記の形です。
変換前
インデックス | 0 | 1 | 2 |
---|---|---|---|
0 | 1a | 1b | 1c |
1 | 2a | 2b | 2c |
2 | 3a | 3b | 3c |
変換後
インデックス | 0 | 1 | 2 |
---|---|---|---|
0 | 1a | 2a | 3a |
1 | 1b | 2b | 3b |
2 | 1c | 2b | 3c |
実装
正方形に対して
まずList自体の数と、それぞれのList<string>の中身の数が同じときの実装です。
実コードとしては以下になります。
static void Main(string[] args)
{
var targetList = new List<List<string>>()
{
new List<string>() {"1a", "1b", "1c"},
new List<string>() {"2a", "2b", "2c"},
new List<string>() {"3a", "3b", "3c"}
};
var resultList = TransposeColumnsAndRows(targetList);
}
private static List<List<string>> TransposeColumnsAndRows(List<List<string>> targetList)
{
var resultList = new List<List<string>>();
foreach (var row in targetList.Select((v, i) => new { v, i }))
{
while (resultList.Count() < row.v.Count())
resultList.Add(new List<string>());
foreach (var col in row.v.Select((v, i) => new { v, i }))
{
resultList[col.i].Add(col.v);
}
}
return resultList;
}
TransposeColumnsAndRowsメソッドで縦横を入れ替えます。
中では何をしているかというと、新たにListを作成して、横の数だけ縦のListを生成し、横のListを順々に詰めているだけです。
結果
resultList の中身は以下のような形になります。
new List<List<string>>()
{
new List<string>() {"1a", "2a", "3a"},
new List<string>() {"1b", "2b", "3b"},
new List<string>() {"1c", "2c", "3c"}
}
正方形でないパターン
ただ、このままだと横のListが空だった場合や、縦と横が同じ数のList以外ではズレが生じます。
下記のようなListだと2dがあふれてしまいますね。
// 変換前
new List<List<string>>()
{
new List<string>() {"1a", "1b", "1c"},
new List<string>() {"2a", "2b", "2c", "2d"},
new List<string>() {"3a", "3b", "3c"}
}
// 変換後
new List<List<string>>()
{
new List<string>() {"1a", "2a", "3a"},
new List<string>() {"1b", "2b", "3b"},
new List<string>() {"1c", "2c", "3c"},
new List<string>() {"2d"}
}
ここの対応に関しては、どう対応するか色々方法はあるとおもいます。
今回は縦に足りない分を指定した文字で埋める形にしてみました。
以下、実装コードです。
static void Main(string[] args)
{
var targetList = new List<List<string>>()
{
new List<string>() {"1a", "1b", "1c"},
new List<string>() {"2a", "2b", "2c", "2d"},
new List<string>() {"3a", "3b", "3c"}
};
var resultList = TransposeColumnsAndRows(targetList, string.Empty);
}
private static List<List<string>> TransposeColumnsAndRows(List<List<string>> targetList, string pad)
{
var resultList = new List<List<string>>();
foreach (var row in targetList.Select((v, i) => new { v, i }))
{
while (resultList.Count() < row.v.Count())
resultList.Add(new List<string>());
foreach (var col in row.v.Select((v, i) => new { v, i }))
{
while (row.i > resultList[col.i].Count())
resultList[col.i].Add(string.Empty);
resultList[col.i].Add(col.v);
}
}
foreach (var row in resultList)
{
while (row.Count() < targetList.Count())
{
row.Add(pad);
}
}
return resultList;
}
結果
new List<List<string>>()
{
new List<string>() {"1a", "2a", "3a"},
new List<string>() {"1b", "2b", "3b"},
new List<string>() {"1c", "2c", "3c"},
new List<string>() {"", "2d", ""}
}
これで、足りない部分がから文字で埋められました。
テーブルのような正方形の形を保ちつつ、縦横を入れ替えることができました。