0

改行文字で区切られた大きな文字列があります。この文字列には 100 行が含まれます。これらの行を改行文字に基づいて20個のチャンクなどの小さなチャンクに分割したいと思います。

文字列変数がこのようなものだとしましょう。

Line1
こちらが
line2 Line3 がこちら
私は Line4

次に、この大きな文字列変数を 2 つの小さなチャンクに分割します。結果は、次のように 2 つの文字列になるはずです。

Line1
これはline2 です


Line3 はこちらです
私は Line4 です

Split 関数を使用すると、期待した結果が得られません。これを達成するのを手伝ってください。

前もってありがとう、
ビジェイ

4

6 に答える 6

3

単純なアプローチ(Environment.NewLineで分割してから、ループして追加):

public static List<string> GetStringSegments(string originalString, int linesPerSegment)
{

    List<string> segments = new List<string>();
    string[] allLines = originalString.Split(new string[] {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries); 
    StringBuilder sb = new StringBuilder();

    int linesProcessed = 0;
    for (int i = 0; i < allLines.Length; i++)
    {
        sb.AppendLine(allLines[i]);
        linesProcessed++;

        if (linesProcessed == linesPerSegment
            || i == allLines.Length-1)
        {
            segments.Add(sb.ToString());
            sb.Clear();
            inesProcessed = 0;
        }
    }

    return segments;
}

上記のアプローチは、最初に文字列を個々の行に分割する必要があり、不要な文字列が作成されるため、少し非効率的です。1000行の文字列は、1000文字列の配列を作成します。文字列をスキャンして次を検索するだけで、これを改善できます\n

public static List<string> GetStringSegments(string original, int linesPerSegment)
{
    List<string> segments = new List<string>();

    int startIndex = 0;
    int newLinesEncountered = 0;

    for (int i = 0; i < original.Length; i++)
    {
        if (original[i] == '\n')
        {
            newLinesEncountered++;
        }

        if (newLinesEncountered == linesPerSegment
            || i == original.Length - 1)
        {
            segments.Add(original.Substring(startIndex, (i - startIndex + 1)));
            startIndex = i + 1;
            newLinesEncountered = 0;
        }
    }

    return segments;
}
于 2012-04-16T06:08:12.457 に答える
2

http://www.make-awesome.com/2010/08/batch-or-partition-a-collection-with-linqのバッチ演算子のようなものを使用できます

string s = "[YOUR DATA]";
var lines = s.Split(new[]{Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries);
foreach(var batch in lines.Batch(20))
{
  foreach(batchLine in batch)
  {
    Console.Writeline(batchLine);
  }
}

static class LinqEx
{
  // from http://www.make-awesome.com/2010/08/batch-or-partition-a-collection-with-linq
  public static IEnumerable<IEnumerable<T>> Batch<T>(this IEnumerable<T> collection,
                int batchSize)
  {
    List<T> nextbatch = new List<T>(batchSize);
    foreach (T item in collection)
    {
      nextbatch.Add(item);
      if (nextbatch.Count == batchSize)
      {
        yield return nextbatch;
        nextbatch = new List<T>(batchSize);
      }
    }
    if (nextbatch.Count > 0)
      yield return nextbatch;
  }
}
于 2012-04-16T05:51:34.867 に答える
1

何人かが言及したように、を使用string.Splitすると文字列全体がメモリに分割され、割り当てが多い操作になる可能性があります。これが、より優れたメモリ パフォーマンスを提供する必要TextReaderがあるクラスとその子孫を持っている理由であり、論理的にもより明確になる可能性があります。

using (var reader = new StringReader(myString))
{
    do
    {
        StringBuilder newString = null;
        StringWriter newStringWriter = null;
        if (lineCounter % 20 == 0)
        {
             newString = new StringBuilder();
             newStringWriter = new StringWriter(newString);
             newStringCollection.Add(newString);
        } 
        string line = reader.ReadLine();
        if (!string.isNullOrEmpty(line))
        {
             newStringWriter.WriteLine(line);
             lineCounter++;
        }
    }
    while (line != null)
}

を使用してStringReader、一度に 1 行ずつ大きな文字列を読み取ります。そして、対応StringWriterする行は、それらの行を新しい文字列に 1 行ずつ書き込みます。20 行ごとに、新しいStringBuilder(および適切なStringWriterラッパー) を開始します。

于 2012-04-16T06:30:48.433 に答える
0

文字列を改行で分割します。次に、文字列を使用しながら、文字列の数をまとめてマージ/フェッチします。

于 2012-04-16T05:44:14.760 に答える
0
string s = "Line1\nThis is line2 \nLine3 is here\nI am Line4";

string [] str = s.split('\n');

List<String> str1 = new List<String>();

for(int i=0; i<str.Length; i+=2)
{
    string ss = str[i];

    if(i+1 <str.Length)
        ss += '\n' + str[i+1];

    str1.Add(ss);
}

str = str1.ToArray();

str の長さが奇数である可能性があるため、条件がループ内でチェックされている場合

于 2012-04-16T05:58:20.863 に答える
0
var strAray = myLongString.Split('\n').ToList();
var skip=0;
var take=20;

var chunk = strAray.Skip(skip).Take(take).ToList();

While(chunk.Count >0)
{
foreach(var line in chunk)
{
// use line string
}
skip++;
chunk = strAray.Skip(skip).Take(take).ToList()
}
于 2012-04-16T06:05:20.790 に答える