Ich habe nach einer eleganten und effizienten Möglichkeit gesucht, eine Zeichenfolge in Ruby in Teilzeichenfolgen einer bestimmten Länge zu zerlegen.
Das Beste, was ich bisher finden konnte, ist Folgendes:
def chunk(string, size)
(0..(string.length-1)/size).map{|i|string[i*size,size]}
end
>> chunk("abcdef",3)
=> ["abc", "def"]
>> chunk("abcde",3)
=> ["abc", "de"]
>> chunk("abc",3)
=> ["abc"]
>> chunk("ab",3)
=> ["ab"]
>> chunk("",3)
=> []
Vielleicht möchten Sie statt chunk("", n)
zurückkehren . Wenn ja, fügen Sie dies einfach als erste Zeile der Methode hinzu:[""]
[]
return [""] if string.empty?
Würden Sie eine bessere Lösung empfehlen?
Bearbeiten
Vielen Dank an Jeremy Ruten für diese elegante und effiziente Lösung: [Bearbeiten: NICHT effizient!]
def chunk(string, size)
string.scan(/.{1,#{size}}/)
end
Bearbeiten
Die string.scan-Lösung benötigt ungefähr 60 Sekunden, um 512k 10000-mal in 1k-Chunks zu zerlegen, verglichen mit der ursprünglichen Slice-basierten Lösung, die nur 2,4 Sekunden dauert.
Antworten:
Verwendung
String#scan
:quelle
/.
Bit bedeutet, dass er alle Zeichen außer Zeilenumbrüchen enthält\n
. Wenn Sie Zeilenumbrüche einfügen möchten, verwenden Siestring.scan(/.{4}/m)
Hier ist eine andere Möglichkeit:
=> ["abc", "def", "ghi", "jkl", "mno", "pqr", "stu", "vwx", "yz"]
quelle
"abcdefghijklmnopqrstuvwxyz".chars.each_slice(3).map(&:join)
Ich denke, dies ist die effizienteste Lösung, wenn Sie wissen, dass Ihre Zeichenfolge ein Vielfaches der Blockgröße hat
und für Teile
quelle
string.length / size
mit(string.length + size - 1) / size
- dieses Muster in C - Code gemeinsam ist , die mit ganzzahligen Abschneiden zu tun hat.Hier ist eine andere Lösung für einen etwas anderen Fall, wenn große Zeichenfolgen verarbeitet werden und nicht alle Blöcke gleichzeitig gespeichert werden müssen. Auf diese Weise speichert es jeweils einzelne Chunks und arbeitet viel schneller als das Schneiden von Strings:
quelle
Ich habe einen kleinen Test gemacht, bei dem ungefähr 593 MB Daten in 18991 32 KB große Teile zerlegt wurden. Ihre Slice + Map-Version lief mindestens 15 Minuten mit 100% CPU, bevor ich Strg + C drückte. Diese Version mit String # Unpack ist in 3,6 Sekunden fertig:
quelle
Die Zurückweisung ist erforderlich, da sie ansonsten das Leerzeichen zwischen den Sätzen enthält. Mein Regex-Fu ist nicht ganz in der Lage zu sehen, wie ich das direkt auf meinem Kopf beheben kann.
quelle
Eine bessere Lösung, die den letzten Teil der Zeichenfolge berücksichtigt, der kleiner als die Blockgröße sein kann:
quelle
Gibt es noch andere Einschränkungen, an die Sie denken? Sonst wäre ich furchtbar versucht, so etwas Einfaches zu tun
quelle
Der schnellste Weg ist mit
regex
.In der ersten Zeile wird das Ergebnis in einer Reihe von Array-Elementen gedruckt. Wenn Sie nur die erste haben möchten.
Beachten Sie, dass
number
dies eine Ganzzahl sein sollte. Ändern Sie auch unter[0]
Berücksichtigung Ihrer Anforderung.quelle