I have been looking for an elegant and efficient way to chunk a string into substrings of a given length in Ruby.
So far, the best I could come up with is this:
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)
=> []
You might want chunk("", n)
to return [""]
instead of []
. If so, just add this as the first line of the method:
return [""] if string.empty?
Would you recommend any better solution?
Edit
Thanks to Jeremy Ruten for this elegant and efficient solution: [edit: NOT efficient!]
def chunk(string, size)
string.scan(/.{1,#{size}}/)
end
Edit
The string.scan solution takes about 60 seconds to chop 512k into 1k chunks 10000 times, compared with the original slice-based solution which only takes 2.4 seconds.
Here is another way to do it:
=> ["abc", "def", "ghi", "jkl", "mno", "pqr", "stu", "vwx", "yz"]
The reject is necessary because it otherwise includes the blank space between sets. My regex-fu isn't quite up to seeing how to fix that right off the top of my head.
A better solution which takes into account the last part of the string which could be less than the chunk size:
Here is another one solution for slightly different case, when processing large strings and there is no need to store all chunks at a time. In this way it stores single chunk at a time and performs much faster than slicing strings:
Use
String#scan
:I think this is the most efficient solution if you know your string is a multiple of chunk size
and for parts