Angenommen, ich hätte eine Zeichenkette:
string str = "1111222233334444";
Wie kann ich diese Zeichenfolge in Stücke einer bestimmten Größe zerlegen?
Die Aufteilung in 4 Größen würde z. B. Zeichenketten ergeben:
"1111"
"2222"
"3333"
"4444"
Angenommen, ich hätte eine Zeichenkette:
string str = "1111222233334444";
Wie kann ich diese Zeichenfolge in Stücke einer bestimmten Größe zerlegen?
Die Aufteilung in 4 Größen würde z. B. Zeichenketten ergeben:
"1111"
"2222"
"3333"
"4444"
static IEnumerable<string> Split(string str, int chunkSize)
{
return Enumerable.Range(0, str.Length / chunkSize)
.Select(i => str.Substring(i * chunkSize, chunkSize));
}
Bitte beachten Sie, dass zusätzlicher Code erforderlich sein kann, um Randfälle korrekt zu behandeln ( null
oder leere Eingabezeichenfolge, chunkSize == 0
, Länge der Eingabezeichenfolge nicht teilbar durch chunkSize
, usw.). Die ursprüngliche Frage spezifiziert keine Anforderungen für diese Randfälle, und im wirklichen Leben können die Anforderungen variieren, so dass sie außerhalb des Anwendungsbereichs dieser Antwort liegen.
In einer Kombination aus den Antworten von dove+Konstatin...
static IEnumerable<string> WholeChunks(string str, int chunkSize) {
for (int i = 0; i < str.Length; i += chunkSize)
yield return str.Substring(i, chunkSize);
}
Dies funktioniert für alle Zeichenketten, die in eine ganze Anzahl von Abschnitten aufgeteilt werden können, und löst andernfalls eine Ausnahme aus.
Wenn Sie Zeichenketten beliebiger Länge unterstützen möchten, können Sie den folgenden Code verwenden:
static IEnumerable<string> ChunksUpto(string str, int maxChunkSize) {
for (int i = 0; i < str.Length; i += maxChunkSize)
yield return str.Substring(i, Math.Min(maxChunkSize, str.Length-i));
}
Der Auftraggeber hat jedoch ausdrücklich erklärt, dass er no brauchen; sie ist etwas länger und schwieriger zu lesen, etwas langsamer. Im Sinne von KISS und YAGNI würde ich mich für die erste Option entscheiden: Sie ist wahrscheinlich die effizienteste Implementierung, die möglich ist, und sie ist sehr kurz, lesbar und, was wichtig ist, löst eine Ausnahme für nicht konforme Eingaben aus.
Warum keine Schleifen? Hier ist etwas, das es ganz gut machen würde:
string str = "111122223333444455";
int chunkSize = 4;
int stringLength = str.Length;
for (int i = 0; i < stringLength ; i += chunkSize)
{
if (i + chunkSize > stringLength) chunkSize = stringLength - i;
Console.WriteLine(str.Substring(i, chunkSize));
}
Console.ReadLine();
Ich weiß nicht, wie Sie mit dem Fall, wo die Zeichenfolge nicht Faktor von 4, aber nicht sagen, Sie Idee ist nicht möglich, nur wundern die Motivation für es, wenn eine einfache for-Schleife es sehr gut tut umgehen würde? Natürlich könnte die oben genannten bereinigt werden und sogar in als eine Erweiterung Methode setzen.
Oder wie in den Kommentaren erwähnt, wissen Sie, dass es dann /4 ist
str = "1111222233334444";
for (int i = 0; i < stringLength; i += chunkSize)
{Console.WriteLine(str.Substring(i, chunkSize));}
Die Grundlage hierfür sind @Taubenlösung sondern als Erweiterungsmethode implementiert.
Vorteile:
Code
public static class EnumerableEx
{
public static IEnumerable<string> SplitBy(this string str, int chunkLength)
{
if (String.IsNullOrEmpty(str)) throw new ArgumentException();
if (chunkLength < 1) throw new ArgumentException();
for (int i = 0; i < str.Length; i += chunkLength)
{
if (chunkLength + i > str.Length)
chunkLength = str.Length - i;
yield return str.Substring(i, chunkLength);
}
}
}
Verwendung
var result = "bobjoecat".SplitBy(3); // bob, joe, cat
Einheitstests aus Gründen der Kürze entfernt (siehe vorherige Revision )
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
19 Stimmen
Warum LINQ oder Regexe verwenden, wenn die Standardfunktionen von C# zur Stringmanipulation dies mit weniger Aufwand und mehr Geschwindigkeit erledigen können? Was passiert außerdem, wenn die Zeichenfolge eine ungerade Anzahl von Zeichen lang ist?
0 Stimmen
Ich würde gerne Schleifen usw. vermeiden. Ich denke, es kann in einer Zeile mit LINQ/Regex getan werden.
8 Stimmen
"Ich möchte Schleifen vermeiden" - warum?
1 Stimmen
Dieses Szenario ist Teil eines viel größeren Problems (die Zeichenfolge ist auch viel größer) und IMO mit Schleifen, hacken Zeichenfolgen usw. ist nicht sehr elegant. StringLength % 4 wird immer 0 sein. Glauben Sie, dass die Verwendung von Schleifen die einzige Lösung ist? Ich möchte keine Kompromisse bei der Leistung eingehen, was ist also die beste Lösung? TIA.
12 Stimmen
Die Verwendung einer einfachen Schleife bringt definitiv die beste Leistung.
0 Stimmen
Sind Sie sicher, dass Linq leistungsfähiger ist als eine for-Schleife? Ich frage mich, was der Unterschied im Unterstreichen der CLR-Sprache am Ende sein würde. Wenn dies wirklich ein Leistungsengpass ist, was seltsam erscheinen würde, dann sollten Sie einige Stresstests durchführen, damit Sie wissen, was bei der erwarteten Belastung schneller ist.
4 Stimmen
nichesoftware.co.nz/blog/200909/linq-vs-loop-performance ist ein ziemlich guter Vergleich zwischen Linq und der tatsächlichen Schleifenbildung über ein Array. Ich bezweifle, dass Linq jemals schneller sein wird als manuell geschriebener Code, da es immer wieder Laufzeitdelegierte aufruft, die nur schwer wegoptimiert werden können. Linq macht aber mehr Spaß :)
2 Stimmen
Ob Sie LINQ oder Regexe verwenden, die Schleife ist immer noch da.
1 Stimmen
Lieber Gott, nein, keine Arrayliste. ArrayListen sind BÖSE