Min*_*ark 85 ruby string chunking
我一直在寻找一种优雅而有效的方法,将一个字符串块化为Ruby中给定长度的子字符串.
到目前为止,我能想到的最好的是:
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)
=> []
Run Code Online (Sandbox Code Playgroud)
您可能想要chunk("", n)返回[""]而不是[].如果是这样,只需将其添加为方法的第一行:
return [""] if string.empty?
Run Code Online (Sandbox Code Playgroud)
你会推荐更好的解决方案吗?
编辑
感谢Jeremy Ruten提供的优雅高效的解决方案:
def chunk(string, size)
string.scan(/.{1,#{size}}/)
end
Run Code Online (Sandbox Code Playgroud)
Jer*_*ten 152
用途String#scan:
>> 'abcdefghijklmnopqrstuvwxyz'.scan(/.{4}/)
=> ["abcd", "efgh", "ijkl", "mnop", "qrst", "uvwx"]
>> 'abcdefghijklmnopqrstuvwxyz'.scan(/.{1,4}/)
=> ["abcd", "efgh", "ijkl", "mnop", "qrst", "uvwx", "yz"]
>> 'abcdefghijklmnopqrstuvwxyz'.scan(/.{1,3}/)
=> ["abc", "def", "ghi", "jkl", "mno", "pqr", "stu", "vwx", "yz"]
Run Code Online (Sandbox Code Playgroud)
Jas*_*son 17
这是另一种方法:
"abcdefghijklmnopqrstuvwxyz".chars.to_a.each_slice(3).to_a.map {|s| s.to_s }
Run Code Online (Sandbox Code Playgroud)
=> ["abc","def","ghi","jkl","mno","pqr","stu","vwx","yz"]
我认为如果你知道你的字符串是块大小的倍数,这是最有效的解决方案
def chunk(string, size)
(string.length / size).times.collect { |i| string[i * size, size] }
end
Run Code Online (Sandbox Code Playgroud)
和零件
def parts(string, count)
size = string.length / count
count.times.collect { |i| string[i * size, size] }
end
Run Code Online (Sandbox Code Playgroud)
这是针对稍微不同的情况的另一种解决方案,在处理大字符串时并且不需要一次存储所有块。通过这种方式,它一次存储单个块,并且执行速度比切片字符串快得多:
io = StringIO.new(string)
until io.eof?
chunk = io.read(chunk_size)
do_something(chunk)
end
Run Code Online (Sandbox Code Playgroud)
小智 6
我做了一个小测试,将大约 593MB 的数据切成 18991 个 32KB 的块。在我按下 ctrl+C 之前,您的 slice+map 版本使用 100% CPU 运行了至少 15 分钟。这个版本使用 String#unpack 在 3.6 秒内完成:
def chunk(string, size)
string.unpack("a#{size}" * (string.size/size.to_f).ceil)
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
31810 次 |
| 最近记录: |