System.Stringクラスには、Splitというメソッドがある。引数で指定された文字で文字列を分割するメソッドなのだが、返却される結果は配列になっている。配列と言う事は、非常に多くの文字列が分割されると、それだけメモリを消費する事になる。
そんなわけで、このメソッドを逐次実行可能な列挙子を返すLINQメソッドとして定義してみる。
public static class LinqExtensions
{
public static IEnumerable<string> SplitAsEnumerable(this string target, params char[] separators)
{
var startIndex = 0;
while (true)
{
var index = target.IndexOfAny(separators, startIndex);
if (index == -1)
{
yield return target.Substring(startIndex);
break;
}
yield return target.Substring(startIndex, index - startIndex);
startIndex = index + 1;
}
}
}
System.String.Splitはインスタンスメンバーなので、Splitというメソッド名にすると呼び出せなくなってしまう。仕方がないので、SplitAsEnumerableという名前で定義した。
var veryLongStringValue = "...";
foreach (var value in veryLongStringValue.SplitAsEnumerable(','))
{
Console.WriteLine("Value={0}", value);
}
これで逐次分割できるようになった。ロジックを拡張して、ダブルクオートで囲まれた文字列を切り出す等の応用が出来ると思う。