Quelle est la meilleure façon de couper une chaîne en morceaux d’une longueur donnée en Ruby?

J’ai cherché un moyen élégant et efficace de découper une chaîne en sous-chaînes d’une longueur donnée en Ruby.

Jusqu’à présent, le mieux que je puisse trouver est le suivant:

def chunk(ssortingng, size) (0..(ssortingng.length-1)/size).map{|i|ssortingng[i*size,size]} end >> chunk("abcdef",3) => ["abc", "def"] >> chunk("abcde",3) => ["abc", "de"] >> chunk("abc",3) => ["abc"] >> chunk("ab",3) => ["ab"] >> chunk("",3) => [] 

Vous pourriez vouloir que chunk("", n) renvoie [""] au lieu de [] . Si c’est le cas, ajoutez ceci comme première ligne de la méthode:

 return [""] if ssortingng.empty? 

Recommanderiez-vous une meilleure solution?

modifier

Merci à Jeremy Ruten pour cette solution élégante et efficace:

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

Utilisez Ssortingng#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"] 

Voici une autre façon de le faire:

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

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

Je pense que c’est la solution la plus efficace si vous savez que votre chaîne est un multiple de la taille du bloc

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

et pour les pièces

 def parts(ssortingng, count) size = ssortingng.length / count count.times.collect { |i| ssortingng[i * size, size] } end 
 test.split(/(...)/).reject {|v| v.empty?} 

Le rejet est nécessaire car il inclut l’espace vide entre les ensembles. Mon regex-fu n’est pas tout à fait à la hauteur de la façon de résoudre ce problème.

Y a-t-il d’autres contraintes que vous avez en tête? Sinon, je serais terriblement tenté de faire quelque chose de simple comme

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