How do you slice or split a string into a specific character in Ruby?

If I had a string like the one below, how would I split it into every third character or any other specified character?

b = "123456789"

The result is the following:

b = ["123","456","789"]

I tried using this method: b.split("").each_slice(3).to_a

But this leads to the following: [["1", "2", "3"], ["4", "5", "6"], ["7", "8", "9"]]

Thank you for your help!

+4
source share
6 answers
b = "123456789"
b.chars.each_slice(3).map(&:join)
# => ["123", "456", "789"]
+6
source

I would use:

b = "123456789"
b.scan(/.{3}/) # => ["123", "456", "789"]

If the OP sample should have been of a different length or had a built-in "\ n", a simple modification works:

b = "123456789"
b.scan(/.{1,3}/) # => ["123", "456", "789"]
b[0..-2].scan(/.{1,3}/) # => ["123", "456", "78"]
"#{ b }\n#{ b }".scan(/.{1,3}/) # => ["123", "456", "789", "123", "456", "789"]

Now, if there is a built-in "\ n" NOT on the even border of "3", it is interrupted:

"#{ b[0..-2] }\n#{ b }".scan(/.{1,3}/) # => ["123", "456", "78", "123", "456", "789"]

OP :

"#{ b[0..-2] }\n#{ b }".delete("\n").scan(/.{1,3}/) # => ["123", "456", "781", "234", "567", "89"]
+6

.

b = "123456789"
b.split("").each_slice(3).map(&:join) # => ["123", "456", "789"]
+5

:

my_s, my_a = '123456789', []
my_a << my_s.slice!(0..2) until my_s.empty?
p my_a # => ["123", "456", "789"]
+5

, . , .

s = "1234567"
(0...s.size / 3).map { |i| s[i * 3, 3] }
# => ["123", "456", "7"]

Benchmark:

require "benchmark"

N = 100000

Benchmark.bm do |x|
    b = "123456789"
    x.report { N.times { (0...b.size / 3).map { |i| b[i * 3, 3] } } }
    x.report { N.times { b.scan(/.{3}/) } }
    x.report { N.times { b.chars.each_slice(3).map(&:join) } }
    x.report { N.times { b.split("").each_slice(3).map(&:join) } }
end

:

$ ruby split3.rb
       user     system      total        real
   0.080000   0.000000   0.080000 (  0.079944)
   0.130000   0.000000   0.130000 (  0.127715)
   0.300000   0.000000   0.300000 (  0.299186)
   0.640000   0.000000   0.640000 (  0.641817)

, , - . . .

+2

, ( , ) , , split :

# Split and include splitting character in next slice
"123456789".split(/(?=[36])/)     # => ["12", "345", "6789"]

# Split and include splitting character in slice
"123456789".split(/(?<=[36])/)    # => ["123", "456", "789"]

# Split and exclude character from slices
"123456789".split(/[36]/)         # => ["12", "45", "789"]

Keep in mind that this uses regular expressions, and for your purposes it might be better to find a way to split the string using a less complicated route (see the delayed answer, which is a rather short and reasonable way to handle this). Depending on the complexity of the shared string, what you split, what to do with the splitting of characters / phrases / etc. Etc., your approach may change.

+2
source

All Articles