コレクションの値を連結して一つの文字列にしたい場合、文字列型に用意された静的メソッドのstring.join<T>()
を利用できます。しかし、この場合、コレクションの要素に対してT.ToString()
が呼ばれるだけなので、DateTime
のリストを任意の書式で連結したいなど、時として物足りない場合がでてきます。
あと、文字列型の静的メソッドというのも何だか気に入りません。
そこで、コレクションの要素に対してデレゲートを利用して任意の書式に変換できるようにしたjoinをIEnumerable
の拡張メソッドにしてみました。
サンプルコード
public static class IEnumerableUtil
{
public static string JoinString<T>(this IEnumerable<T> values, string separator, Func<T, string> converter = null)
{
if (converter != null)
{
List<string> buff = new List<string>();
foreach (var item in values)
buff.Add(converter(item));
return string.Join(separator, buff);
}
else
return string.Join(separator, values);
}
}
※ IEnumerable
には既にJoin
という同名のメソッドが存在したため、JoinString
に変更しました。(2014.3.27)
使い方
IEnumerable
に対して拡張メソッドを定義しているので、Listはもちろん単純な配列に対しても呼び出すことができます。
static void JoinTest()
{
Console.WriteLine((new int[] { 10,23,46,54,82 }).JoinString(","));
Console.WriteLine((new DateTime[] {
new DateTime(2014,1,1),
new DateTime(2014,2,2),
new DateTime(2014,3,18)
}).JoinString(",", v => v.ToString("yyyy年MM月dd日")));
}
出力例
10,23,46,54,82
2014年01月01日,2014年02月02日,2014年03月18日
追記:Select() を利用したバージョン (2014.3.27)
コメント欄でSelect()
を利用した方が良いのでは?という指摘をいただきました。恥ずかしながらSelect()
というメソッドの存在を知らなかったのですが、rubyなどでいうmap
に相当するメソッドのようです。
Select()
を利用することで上記コードは以下のように簡潔に記述することができました。
// Select()利用バージョン
public static class IEnumerableUtil
{
public static string JoinString<T>(this IEnumerable<T> values, string glue, Func<T, string> converter = null)
{
if (converter != null)
return string.Join(glue, values.Select(converter));
else
return string.Join(glue, values);
}
}