Pregunta ¿Cuál es la mejor manera de cortar una cuerda en trozos de una longitud determinada en Ruby?


He estado buscando una manera elegante y eficiente de dividir una cadena en subcadenas de una longitud determinada en Ruby.

Hasta ahora, lo mejor que se me ocurrió fue esto:

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)
=> []

Podrías querer chunk("", n) regresar [""] en lugar de []. Si es así, simplemente agregue esto como la primera línea del método:

return [""] if string.empty?

¿Recomendarías alguna mejor solución?

Editar

Gracias a Jeremy Ruten por esta solución elegante y eficiente:

def chunk(string, size)
    string.scan(/.{1,#{size}}/)
end

76
2018-04-16 01:06


origen


Respuestas:


Utilizar 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"]

137
2018-04-16 01:26



Aquí hay otra manera de hacerlo:

"abcdefghijklmnopqrstuvwxyz".chars.to_a.each_slice(3).to_a.map {|s| s.to_s }

=> ["abc", "def", "ghi", "jkl", "mno", "pqr", "stu", "vwx", "yz"]


16
2018-02-04 20:04



Creo que esta es la solución más eficiente si sabes que tu cadena es un múltiplo de tamaño de fragmento

def chunk(string, size)
    (string.length / size).times.collect { |i| string[i * size, size] }
end

y por partes

def parts(string, count)
    size = string.length / count
    count.times.collect { |i| string[i * size, size] }
end

2
2017-07-26 14:00



test.split(/(...)/).reject {|v| v.empty?}

El rechazo es necesario porque de lo contrario incluye el espacio en blanco entre los conjuntos. Mi regex-fu no está a la altura de ver cómo arreglar eso directamente de mi cabeza.


1
2018-04-16 01:20



¿Hay alguna otra restricción que tengas en mente? De lo contrario, estaría tremendamente tentado de hacer algo tan simple como

[0..10].each {
   str[(i*w),w]
}

0
2018-04-16 01:15