タスクを 2 つの部分に分割します。
- 文字列をコンマで分割する
- 最初の N 個の値のみを取得する
String.Split
幸いなことに、C# では、最初の処理を処理し、2 番目の処理を LINQTake
メソッドで処理することで、これらの両方を非常に単純にします。
var items = text.Split(',')
.Take(itemLimit);
または、リストを作成する場合:
var items = text.Split(',')
.Take(itemLimit)
.ToList();
本当に必要でない限り、コンマ区切りの文字列に戻すことはしません。データの最も自然な表現 (たとえば a List<string>
) をできるだけ長く保持します。必要に応じて、 を使用してString.Join
ください。
「レイジースプリッター」を作成することで、部分をより効率的にすることができますSplit
が、非常に長い文字列を取得することが予想され、少数のアイテムのみを保持したい場合を除き、IMO の利点はほとんどありません。次のようになります。
public static IEnumerable<string> LazySplit(this string text, string separator)
{
int start = 0;
while (true)
{
int end = text.IndexOf(separator, start);
if (end == -1)
{
// Note: if the string ends with the separator, this will yield
// an empty string
yield return text.Substring(start);
yield break; // This will terminate the otherwise-infinite loop
}
yield return text.Substring(start, end - start);
start = end + separator.Length;
}
}
次に、使用法コードは前と似ています。
var items = text.LazySplit(",")
.Take(itemLimit)
.ToList();
または、本当に文字列に保持する必要がある場合は、N 番目のコンマを見つけるために何かを記述しSubstring
、文字列の最初の部分を取得するために使用できます。
// TODO: Improve the name :)
public static string TruncateAfterSeparatorCount(string text,
string separator,
int count)
{
// We pretend that the string "starts" with a separator before index 0.
int index = -separator.Length;
for (int i = 0; i < count; i++)
{
int nextIndex = text.IndexOf(separator, index + separator.Length);
// Not enough separators. Return the whole string. Could throw instead.
if (nextIndex == -1)
{
return text;
}
index = nextIndex;
}
// We need to handle the count == 0 case, where index will be negative...
return text.Substring(0, Math.Max(index, 0));
}
しかし、私が言うように、List<string>
可能であれば、私は個人的にアプローチを使用しようとします. Split
上記のコードは、 / Take
/ToList
よりも効率的ですが、明らかにはるかに複雑です。必要があることが証明された場合にのみ、より効率的で複雑なコードを使用してください。