Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Slice string from end in Ruby

How can I split a string into multiple substrings of equal length but from back?

For example if string is: "ABCDEFGH", then I want an array of each string of length 3 as:

["FGH", "CDE", "AB"]
like image 693
user3075906 Avatar asked Aug 10 '26 07:08

user3075906


2 Answers

I think that this does what you're asking:

> "ABCDEFGH".reverse.scan(/.{1,3}/).each { |x| x.reverse! }
=> ["FGH", "CDE", "AB"]

Here's a quick explanation:

.reverse reverses the string so that it is "HGFEDCBA" instead of "ABCDEFGH".

.scan(/.{1,3}/) converts the string into an array with each element of the array containing 3 characters (if the string isn't divisible by 3 then the last element of the array may have 1 or 2 characters).

.each { |x| x.reverse! } reverses the characters in each element of the array.

You could define a function like this:

def slice_string_from_end(s)
  s.reverse.scan(/.{1,3}/).each { |x| x.reverse! }
end

Then you can use:

slice_string_from_end("ABCDEFGH")
like image 125
Andrew Hendrie Avatar answered Aug 13 '26 06:08

Andrew Hendrie


You can accomplish this using each_slice, but you'll need to reverse the string first, and then re-reverse each individual slice:

x = "ABCDEFGH"
x.chars.reverse.each_slice(3).map(&:reverse).map(&:join)
=> ["FGH", "CDE", "AB"]
  • split the string into a character array (x.chars)
  • reverse the array (.reverse)
  • slice the array into sub-arrays of 3 characters (.each_slice(3))
  • reverse each sub-array (.map(&:reverse))
  • join each sub-array back into a string (.map(&:join))
like image 27
meagar Avatar answered Aug 13 '26 05:08

meagar