I want to split a string to an array which include each 2 word of original string as below:
Ex:
str = "how are you to day"
output = ["how are", "are you", "you to", "to day"]
Any one can give solution? thank so much!
I want to split a string to an array which include each 2 word of original string as below:
Ex:
str = "how are you to day"
output = ["how are", "are you", "you to", "to day"]
Any one can give solution? thank so much!
Input
str = "how are you to day"
Code
p str.split(/\s/)
.each_cons(2)
.map { |str| str.join(" ") }
Output
["how are", "are you", "you to", "to day"]
map(&:itself) = map{|x| x}split returns an array. You can save memory by returning an enumerator if you replace str.split(/\s/) (or just str.split) with gsub(/\w+/).Here is one approach, which uses a regex trick to duplicate the second through second to last words in the input string:
input = "how are you to day"
input = input.gsub(/(?<=\s)(\w+)(?=\s)/, "\\1 \\1")
output = input.scan(/\w+ \w+/).flatten
puts output
This prints:
how are
are you
you to
to day
Here are a couple ways to do that. Both use the form of String#gsub that takes a regular expression as its argument and no block, returning an enumerator. This form of gsub merely generates matches of the regular expression; it has nothing to do with string replacement.
str = "how are you to day"
Use a regular expression that contains a positive lookahead
r = /\w+(?=( \w+))/
str.gsub(r).with_object([]) { |s,a| a << s + $1 }
#=> ["how are", "are you", "you to", "to day"]
I've chained the enumerator str.gsub(r) to Enumerator#with_object. String#gsub is a convenient replacement for String#scan when the regular expression contains capture groups. See String#scan for for an explanation of how it treats capture groups.
We can write the regular expression in free-spacing mode to make it self-documenting.
r = /
\w+ # match >= 1 word characters
(?= # begin a positive lookahead
( \w+) # match a space followed by >= 1 word characters and save
# to capture group 1
) # end positive lookahead
/x # invoke free-spacing regex definition mode
Enumerate pairs of successive words in the sting
enum = str.gsub(/\w+/)
loop.with_object([]) do |_,a|
a << enum.next + ' ' + enum.peek
end
#=> ["how are", "are you", "you to", "to day"]
See Enumerator#next and Enumerator#peek. After next returns the last word in the string peek raises a StopIteration exception which is handled by loop by breaking out of the loop and returning the array a. See Kernel#loop.
Here’s another option:
str = "how are you to day"
arr = str.split
new_arr = []
(arr.length-1).times {new_arr.push(arr[0..1].join(" ")); arr.shift}
print new_arr #=> ["how are", "are you", "you to", "to day"]
new_arr = [] and replace the next line with (arr.length-1).times.map { |i| arr[i] + ' ' + arr[i+1] }.