Frage

Vielleicht eine grundlegende Frage, aber lassen Sie uns sagen, dass ich eine Zeichenfolge, die 2000 Zeichen lang ist, ich brauche jede Saite in max 512 Zeichen Stücke aufzuspalten.

Gibt es eine schöne Art und Weise, wie eine Schleife oder so, dies zu tun?

War es hilfreich?

Lösung

So etwas wie folgt aus:

private IList<string> SplitIntoChunks(string text, int chunkSize)
{
    List<string> chunks = new List<string>();
    int offset = 0;
    while (offset < text.Length)
    {
        int size = Math.Min(chunkSize, text.Length - offset);
        chunks.Add(text.Substring(offset, size));
        offset += size;
    }
    return chunks;
}

oder einfach nur iterieren:

private IEnumerable<string> SplitIntoChunks(string text, int chunkSize)
{
    int offset = 0;
    while (offset < text.Length)
    {
        int size = Math.Min(chunkSize, text.Length - offset);
        yield return text.Substring(offset, size);
        offset += size;
    }
}

Beachten Sie, dass diese spaltet sich in Stücke von UTF-16 Code-Einheiten, die als Aufspaltung in Stücke von Unicode-Codepunkten, die wiederum nicht das gleiche wie Spaltung sein kann in Stücke von Glyphen nicht ganz das gleiche ist.

Andere Tipps

Obwohl diese Frage mittlerweile eine akzeptierte Antwort hat, ist hier eine kurze Version mit Hilfe von regulären Ausdrücken. Puristen mögen es nicht (verständlicherweise), aber wenn Sie eine schnelle Lösung benötigen und Sie sind handlich mit regulären Ausdrücken, dies kann es sein. Die Leistung ist ziemlich gut, überraschend:

string [] split = Regex.Split(yourString, @"(?<=\G.{512})");

Was sie tut? Negativer Look-rückwärts und die Erinnerung an die letzte Position mit \G. Es wird auch das letzte Stück fangen, auch wenn es mit 512 nicht teilbaren ist.

Jon-Implementierung und die Ausbeute mit Stichwort.

IEnumerable<string> Chunks(string text, int chunkSize)
{
    for (int offset = 0; offset < text.Length; offset += chunkSize)
    {
        int size = Math.Min(chunkSize, text.Length - offset);
        yield return text.Substring(offset, size);
    }
}
static IEnumerable<string> Split(string str, int chunkSize)    
{   
    int len = str.Length;
    return Enumerable.Range(0, len / chunkSize).Select(i => str.Substring(i * chunkSize, chunkSize));    
}

Quelle: eine Zeichenfolge in Stücke Splitting von einer bestimmten Größe

Ich werde es wagen, eine LINQified Version von Jon-Lösung zur Verfügung zu stellen, auf der Grundlage der Tatsache, dass der string Typ implementiert IEnumerable<char>:

private IList<string> SplitIntoChunks(string text, int chunkSize)
{
    var chunks = new List<string>();
    int offset = 0;
    while(offset < text.Length) {
        chunks.Add(new string(text.Skip(offset).Take(chunkSize).ToArray()));
        offset += chunkSize;
    }
    return chunks;
}

Die meisten der Antwort kann den gleichen Fehler haben. einen leeren Text gegeben sie nichts bringen wird. Wir (I) erwarten, dass mindestens zurück zu bekommen, dass leere Zeichenkette (gleiches Verhalten als Split auf einem char nicht in der Zeichenfolge, die ein Element geben zurück: die angegebene Zeichenfolge)

so sollten wir Schleife mindestens einmal alle Zeiten (basierend auf Jons Code):

IEnumerable<string> SplitIntoChunks (string text, int chunkSize)
{
    int offset = 0;
    do
    {
        int size = Math.Min (chunkSize, text.Length - offset);
        yield return text.Substring (offset, size);
        offset += size;
    } while (offset < text.Length);
}

oder mit einem für ( Edited : Nach etwas mehr mit diesem liebäugelt, fand ich einen besseren Weg, den Fall zu behandeln chunkSize größer als Text ):

IEnumerable<string> SplitIntoChunks (string text, int chunkSize)
{
    if (text.Length <= chunkSize)
        yield return text;
    else
    {
        var chunkCount = text.Length / chunkSize;
        var remainingSize = text.Length % chunkSize;

        for (var offset = 0; offset < chunkCount; ++offset)
            yield return text.Substring (offset * chunkSize, chunkSize);

        // yield remaining text if any
        if (remainingSize != 0)
            yield return text.Substring (chunkCount * chunkSize, remainingSize);
    }
}

Das könnte auch mit der do / while-Schleife verwendet werden;)

Allg Erweiterungsmethode:

using System;
using System.Collections.Generic;
using System.Linq;

public static class IEnumerableExtensions
{
  public static IEnumerable<IEnumerable<T>> SplitToChunks<T> (this IEnumerable<T> coll, int chunkSize)
  {
    int skipCount = 0;
    while (coll.Skip (skipCount).Take (chunkSize) is IEnumerable<T> part && part.Any ())
    {
      skipCount += chunkSize;
      yield return part;
    }
  }
}

class Program
{
  static void Main (string[] args)
  {
    var col = Enumerable.Range(1,1<<10);
    var chunks = col.SplitToChunks(8);

    foreach (var c in chunks.Take (200))
    {
      Console.WriteLine (string.Join (" ", c.Select (n => n.ToString ("X4"))));
    }

    Console.WriteLine ();
    Console.WriteLine ();

    "Split this text into parts that are fifteen characters in length, surrounding each part with single quotes and output each into the console on seperate lines."
      .SplitToChunks (15)
      .Select(p => $"'{string.Concat(p)}'")
      .ToList ()
      .ForEach (p => Console.WriteLine (p));

    Console.ReadLine ();
  }
}

So etwas?

Calculate eachLength = StringLength / WantedCharLength
Then for (int i = 0; i < StringLength; i += eachLength)
SubString (i, eachLength);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top