Angenommen, ich hätte eine Zeichenfolge:
string str = "1111222233334444";
Wie kann ich diese Saite in Stücke von einiger Größe zerlegen?
Wenn Sie dies beispielsweise in Größen von 4 aufteilen, werden Zeichenfolgen zurückgegeben:
"1111"
"2222"
"3333"
"4444"
Antworten:
Bitte beachten Sie, dass möglicherweise zusätzlicher Code erforderlich ist, um Kantenfälle ordnungsgemäß zu behandeln (
null
oder leere Eingabezeichenfolgen,chunkSize == 0
nicht durch teilbare Länge der EingabezeichenfolgenchunkSize
usw.). Die ursprüngliche Frage enthält keine Anforderungen für diese Randfälle, und im wirklichen Leben können die Anforderungen variieren, sodass sie nicht in den Geltungsbereich dieser Antwort fallen.quelle
(i * chunkSize + chunkSize <= str.Length) ? chunkSize : str.Length - i * chunkSize
. Ein weiteres Problem ist, dass diese Funktion nicht berücksichtigt, dass str null ist. Dies kann behoben werden, indem die gesamte return-Anweisung in einen anderen ternären Ausdruck eingeschlossen wird :(str != null) ? ... : Enumerable.Empty<String>();
.str.Length / chunkSize
umdouble length = str.Length; double size = chunkSize; int count = (int)Math.Ceiling(length/size); return Enumerable.Range(0, count)...
StringLength % 4 will always be 0
. WennLinq
es nicht so einfach zu verstehen ist, gibt es andere Antworten, die Schleifen und Ausbeuten verwenden. Jeder kann die Lösung wählen, die ihm am besten gefällt. Sie können Ihren Code als Antwort posten und die Leute werden gerne dafür stimmen.In einer Kombination aus Tauben + Konstatins Antworten ...
Dies funktioniert für alle Zeichenfolgen, die in eine ganze Anzahl von Blöcken aufgeteilt werden können, und löst ansonsten eine Ausnahme aus.
Wenn Sie Zeichenfolgen beliebiger Länge unterstützen möchten, können Sie den folgenden Code verwenden:
Das OP erklärte jedoch ausdrücklich, dass er dies nicht benötige; es ist etwas länger und schwerer zu lesen, etwas langsamer. Im Sinne von KISS und YAGNI würde ich mich für die erste Option entscheiden: Es ist wahrscheinlich die effizienteste Implementierung, die möglich ist, und es ist sehr kurz, lesbar und löst vor allem eine Ausnahme für fehlerhafte Eingaben aus.
quelle
Warum nicht Loops? Hier ist etwas, das es ganz gut machen würde:
Ich weiß nicht, wie Sie mit dem Fall umgehen würden, in dem die Zeichenfolge nicht den Faktor 4 hat, aber nicht zu sagen, dass Ihre Idee nicht möglich ist. Ich frage mich nur, warum eine einfache for-Schleife dies sehr gut macht. Offensichtlich könnte das Obige gereinigt und sogar als Erweiterungsmethode eingesetzt werden.
Oder wie in den Kommentaren erwähnt, wissen Sie, dass es dann / 4 ist
quelle
int chunkSize = 4
außerhalb der Schleife ziehen. Es wird nur beim letzten Durchgang geändert.i += chunkSize
stattdessen verwendet hätte.str.Length
aus der Schleife heraus und in eine lokale Variable ziehen. Der C # -Optimierer kann möglicherweise die Array-Länge inline setzen, aber ich denke, dass der geschriebene Code einen Methodenaufruf für jede Schleife ausführt, was nicht effizient ist, da sich die Größe vonstr
nie ändert.Mit regulären Ausdrücken und Linq :
Ich finde das besser lesbar, aber es ist nur eine persönliche Meinung. Es kann auch ein Einzeiler sein :).
quelle
\d
Zeichenklasse durch ein.
und zu ersetzen und anzugebenRegexOptions.Singleline
.Dies basiert auf der @ dove-Lösung jedoch als Erweiterungsmethode implementiert.
Leistungen:
Code
Verwendung
Unit-Tests wurden der Kürze halber entfernt (siehe vorherige Überarbeitung )
quelle
if (str.Length == 0) yield return String.Empty; else { for... }
IEnumerable
in ein Array umwandeln, insbesondere nicht implizit.Chunkify
. Es ist nicht meine, ich erinnere mich nicht, wo ich diesen Namen gesehen habe, aber es fühlte sich sehr gut für mich anWie ist das für einen Einzeiler?
Bei dieser Regex spielt es keine Rolle, ob der letzte Block weniger als vier Zeichen enthält, da immer nur die Zeichen dahinter angezeigt werden.
Ich bin mir sicher, dass dies nicht die effizienteste Lösung ist, aber ich musste sie einfach rauswerfen.
quelle
target.Lenght % ChunckSize == 0
eine zusätzliche leere Zeile zurückgegeben, z. B.List<string> result = new List<string>(Regex.Split("fooo", @"(?<=\G.{4})", RegexOptions.Singleline));
Es ist nicht schön und es ist nicht schnell, aber es funktioniert, es ist ein Einzeiler und es ist LINQy:
quelle
ToCharArray
ist unnötig dastring
istIEnumerable<char>
.Ich musste kürzlich etwas schreiben, das dies bei der Arbeit erreicht, also dachte ich, ich würde meine Lösung für dieses Problem veröffentlichen. Als zusätzlichen Bonus bietet die Funktionalität dieser Lösung eine Möglichkeit, die Zeichenfolge in die entgegengesetzte Richtung zu teilen, und sie verarbeitet Unicode-Zeichen korrekt, wie zuvor von Marvin Pinto erwähnt. Hier ist es also:
Hier ist auch ein Bildlink zu den Ergebnissen der Ausführung dieses Codes: http://i.imgur.com/16Iih.png
quelle
{str.ToString()}
am Ende Ihrer ersten IF-Anweisung. Bist du sicher, dass du es nicht so gemeint haststr.String
? Ich hatte ein Problem mit dem obigen Code, nahm diese Änderung vor und alles funktionierte.Dies sollte viel schneller und effizienter sein als die Verwendung von LINQ oder anderen hier verwendeten Ansätzen.
quelle
quelle
Sie können morelinq von Jon Skeet verwenden. Verwenden Sie Batch wie:
Dies gibt 4 Chunks für die Zeichenfolge zurück
"1111222233334444"
. Wenn die Zeichenfolgenlänge kleiner oder gleich der Blockgröße ist,Batch
wird die Zeichenfolge als einziges Element von zurückgegebenIEnumerable<string>
Für die Ausgabe:
und es wird geben:
quelle
und ein anderer Ansatz:
quelle
Sechs Jahre später o_O
Nur weil
oder
AFAIK alle Randfälle werden behandelt.
quelle
Einfach und kurz:
quelle
.
?Die Länge der Eingabezeichenfolge, die nicht durch chunkSize teilbar ist, wird korrekt behandelt.
Bitte beachten Sie, dass möglicherweise zusätzlicher Code erforderlich ist, um Kantenfälle ordnungsgemäß zu behandeln (null oder leere Eingabezeichenfolge, chunkSize == 0).
quelle
Ein wichtiger Tipp, wenn die Zeichenfolge, die aufgeteilt wird, alle Unicode-Zeichen unterstützen muss.
Wenn die Zeichenfolge internationale Zeichen wie unterstützen soll
𠀋
, teilen Sie die Zeichenfolge mithilfe der System.Globalization.StringInfo-Klasse auf. Mit StringInfo können Sie die Zeichenfolge basierend auf der Anzahl der Textelemente aufteilen.Die obige Zeichenfolge hat eine Länge von 2, da die
String.Length
Eigenschaft in diesem Fall die Anzahl der Char-Objekte und nicht die Anzahl der Unicode-Zeichen zurückgibt.quelle
Beste, einfachste und allgemeinste Antwort :).
quelle
Substring
Überladung, für die der Parameter length nicht erforderlich istoriginalString.Substring(i)
. Auch können Sie>
statt>=
in Ihrem Scheck verwenden.Persönlich bevorzuge ich meine Lösung :-)
Es behandelt:
Es wird als Erweiterungsmethode implementiert und berechnet die Anzahl der Chunks, die zuvor generiert werden sollen. Der letzte Block wird überprüft, da er kürzer sein muss, falls die Textlänge kein Vielfaches ist. Sauber, kurz, leicht zu verstehen ... und funktioniert!
quelle
quelle
Ich denke, das ist eine direkte Antwort:
Und es deckt Randfälle ab.
quelle
Ich weiß, dass die Frage Jahre alt ist, aber hier ist eine Rx-Implementierung. Es behandelt das
length % chunkSize != 0
Problem sofort:quelle
Ich habe etwas auf Joãos Lösung aufgebaut. Was ich anders gemacht habe, ist, dass Sie in meiner Methode tatsächlich angeben können, ob Sie das Array mit den verbleibenden Zeichen zurückgeben möchten oder ob Sie sie abschneiden möchten, wenn die Endzeichen nicht mit Ihrer erforderlichen Blocklänge übereinstimmen. Ich denke, es ist ziemlich flexibel und das Code ist ziemlich einfach:
quelle
quelle
Leicht geändert, um Teile zurückzugeben, deren Größe nicht gleich chunkSize ist
quelle
List
anIEnumerable
; Alles, was Sie tun müssen, ist, listenspezifische Funktionen auszublenden, die Sie möglicherweise verwenden möchten. Es gibt überhaupt keinen Nachteil, nur das zurückzugebenList
.Ich kann mich nicht erinnern, wer mir das gegeben hat, aber es funktioniert großartig. Ich habe eine Reihe von Möglichkeiten getestet, um Aufzählbare Typen in Gruppen aufzuteilen. Die Nutzung wäre einfach so ...
Der Erweiterungscode würde so aussehen ...
quelle
quelle
i += offSet
in Ihrenfor
Ausdruck.Geändert (jetzt akzeptiert es alle nicht null
string
und alle positivenchunkSize
) Konstantin Spirins Lösung:Tests:
quelle
Demo
quelle
Basierend auf anderen Posterantworten, zusammen mit einigen Verwendungsbeispielen:
quelle
Verwenden der Puffererweiterungen aus der IX-Bibliothek
quelle