0

「A、B、C、D、E、F、G」などのカンマ区切りの文字列を取得し、リスト内の最初の x 個のアイテムのみを返す、あなたが知っている最良/最もクリーンな方法は何ですか? したがって、x = 5 の場合、結果は "A,B,C,D,E" になります。

これを行うにはさまざまな方法があることを知っています。「forループ」でカンマを数えてから、文字列を切り捨てます。文字列を配列またはリストに分割し、最後の x 個のアイテムを削除します。

私が知らない、よりクリーンで効率的なオプションはありますか? これについてどう思いますか?

前もって感謝します!!グレッグ

4

7 に答える 7

5

タスクを 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よりも効率的ですが、明らかにはるかに複雑です。必要があることが証明された場合にのみ、より効率的で複雑なコードを使用してください。

于 2013-03-27T16:16:37.277 に答える
3

これを試して:

string.Join("," , str.Split(",").Take(5));

または、定期的に行う場合は、そのための拡張メソッドを作成できます。

于 2013-03-27T16:16:07.243 に答える
0

Stringこれは、 (Take() ではなく) メソッドのみで実行する場合に機能するはずです。

string.Join(",", s.Split(","), 0, 5);

各要素が 1 文字のみであることがわかっている場合は、次のことができます。

s.Substring(0, 2*x - 1);
于 2013-03-27T16:30:26.957 に答える
0
    string[] List = SubList(5);
    string Output = string.Join(",", List);

private string[] SubList(int p)
{
    string[] List = new string[] { "A", "B", "C", "D", "E", "F" };
    string[] List2 = new string[p];
    for (int i = 0; i < p; i++)
        List2[i] = List[i];
    return List2;
}
于 2013-03-27T16:19:08.537 に答える
0

おそらく aSplitと a Take.

これを試して:

string yourString = "A,B,C,D,E,F,G";
List<string> items = yourString.Split(',')
    .Take(5)
    .ToList();
string output = string.Join(",", items);
于 2013-03-27T16:16:47.343 に答える
0
string[] words = s.Split(',').Take(5);
于 2013-03-27T16:16:54.813 に答える
0

楽しみのために-正規表現/文字列メソッドのみを使用します(この現実の世界では正規表現を使用しません-そうすると、2つの問題が発生します):

string.SubString(0,Regex.Matches(string,",")[x-1].Index);
于 2013-03-27T16:34:58.007 に答える