How do I reverse words not the characters using Ruby? - ruby

I want to reverse the words of a text file:
If my input is:
Hello World
My output should be:
World Hello
I tried this:
File.open('teste.txt').each_line do |line|
print line.reverse.gsub(/\n/,"")
end
but I got the characters reversed.

"Hello World".split.reverse.join(" ")
=> "World Hello"
It splits the string into an array with a whitespace being the default delimiter. Then it reverses the array and concatenates the strings in the array using a white space as well.
Your solution should look like this:
File.open("test.txt").each_line do |line|
puts line.split.reverse.join(" ")
end
puts appends a linebreak after the output, while print does not. This is neccessary, because split discards the original linebreak on each line, when splitting it into an array of words.

Break string into words and reverse that.
"Hello World".split.reverse.join(' ') # => "World Hello"

Split the string on spaces, reverse it, then join them together.
You could make a method to do it as such:
def reverse_words(string)
return string.split(" ").reverse.join(" ")
end
then later, call that method with:
print reverse_words("Hello World")
Or set a string to the returned value:
reversed_string = reverseWords("Hello World")

Related

index out of string, ruby

Here's a small part of my code, pretty self explanatory, it copies all characters to temp from input and skips spaces.
input = gets.to_s.chomp
temp=String.new
for i in 0..input.length-1
if (input[i]==" ")
next
else
temp[i]=input[i]
end
end
puts "#{temp},END"
gets
However, i tested it with a 'hello world' input, and it should've given me helloworld But i'm getting
8:in '[]=':index 6 out of string(IndexError)
meaning the problem starts while it's skipping the space, for some reason.
keep in mind that i don't get any errors if i put a string that doesn't contain a space
Whenever string manipulation is required, it may be desirable to convert the string to an array of its parts, manipulate those parts and then join them back into a string, but more often as not it is simpler to just operate on the string itself, mainly using methods from the class String. Here you could Kernel#puts the following.
"%s END" % gets.delete(" \n")
#=> "helloworld"
String#delete removes both spaces and the return character ("\n") that Kernel#gets tacks onto the end of the string that is entered. A variant of this is "%s END" % gets.chomp.delete(" ").
Another way would be to puts
"%s END" % gets.gsub(/\s/, '')
#=> "helloworld"
The regular expression /\s/, causes String#gsub to remove all whitespace, which includes both spaces (and tabs) that are entered and the "\n" that gets tacks on to the end of the string.
I guess your error is due to the difference between the string 'hello world' and that you're "rejecting" whitespaces. In such case, for each whitespace in the string being used, the temp will have one less.
You can assign the input[i] when isn't a whitespace to the temp variable in the position temp.size, this way you don't skip indexes.
It could be temp[temp.size] or just modifying temp with +=.
for i in 0...input.size
if input[i] == ' '
next
else
temp[temp.size] = input[i]
end
end
Note you can replace the for loop for each (the Ruby way):
input = 'hello world'
temp = ''
(0...input.size).each do |index|
input[index] == ' ' ? next : temp[temp.size] = input[index]
end
# helloworld
If you want to skip all white spaces from your input and print the output, you can do so with a one-liner:
puts "#{gets.chomp.split.join}, END"
In ruby, you hardly need to write loops using for construct unlike other traditional languages like Java.

How to replace a specific character in a string along with the immediate next character

I have a string of text:
string = "%hello %world ho%w is i%t goin%g"
I want to return the following:
"Hello World hoW is iT goinG
The % sign is a key that tells me the next character should be capitalized. The closest I have gotten so far is:
#thing = "%this is a %test this is %only a %test"
if #thing.include?('%')
indicator_position = #thing.index("%")
lowercase_letter_position = indicator_position + 1
lowercase_letter = #thing[lowercase_letter_position]
#thing.gsub!("%#{lowercase_letter}","#{lowercase_letter.upcase}")
end
This returns:
"This is a Test this is %only a Test"
It looks like I need to iterate through the string to make it work as it is only replacing the lowercase 't' but I can't get it to work.
You can do this with gsub and a block:
string.gsub(/%(.)/) do |m|
m[1].upcase
end
Using a block allows you to run arbitrary code on each match.
Inferior to #tadman, but you could write:
string.gsub(/%./, &:upcase).delete('%')
#=> "Hello World hoW is iT goinG

Ruby newline use of two \n

I have a question about the need for the use of \n\n to make a newline.
Please see below examples.
If I do ..
puts "hello"
puts "hi"
or
puts "hello\n"
puts "hi"
The output is..
hello
hi
If I do ..
puts "hello\n\n"
puts "hi"
The output is..
hello
hi
Why do I need \n\n to make one extra newline?
Why doesn't the single \n make any difference?
From the documentation:
puts(obj, ...) → nil
Writes the given objects to ios as with IO#print. Writes a record separator (typically a newline) after any that do not already end with a newline sequence. If called with an array argument, writes each element on a new line. If called without arguments, outputs a single record separator.
The purpose of puts is to ensure the string ends with the newline character.
If there is none, then one newline character will be appended.
If there is one or more, no newline character will be appended.
The other answers here nailed it.
If you want to avoid the magic handling of \n, try using print instead of puts. print outputs your string literally, with no line ending unless you put it there.
> 3.times { print 'Zap' }
ZapZapZap=> 3
> 3.times { puts 'Zap' }
Zap
Zap
Zap
=> 3

Split a string at every occurrence of particular character?

I would like to pass a sequence of characters into a function as a string and have it return to me that string split at the following characters:
# # $ % ^ & *
such that if the string is
'hey#man^you*are#awesome'
the program returns
'hey man you are awesome'
How can I do this?
To split the string you can use String#split
'hey#man^you*are#awesome'.split(/[##$%^&*]/)
#=> ["hey", "man", "you", "are", "awesome"]
to bring it back together, you can use Array#join
'hey#man^you*are#awesome'.split(/[##$%^&*]/).join(' ')
#=> "hey man you are awesome"
split and join should be self-explanatory. The interesting part is the regular expression /[##$%^&*]/ which matches any of the characters inside the character class [...]. The above code is essentially equivalent to
'hey#man^you*are#awesome'.gsub(/[##$%^&*]/, ' ')
#=> "hey man you are awesome"
where the gsub means "globally substitute any occurence of ##$%^&* with a space".
You could also use String#tr, which avoids the need to convert an array back to a string:
'hey#man^you*are#awesome'.tr('##$%^&*', ' ')
#=> "hey man you are awesome"

How to split a string and skip whitespace?

I have a string like " This is a test ". I want to split the string by the space character. I do it like this:
puts " This is a test ".strip.each(' ') {|s| puts s.strip}
The result is:
This
is
a
test
This is a test
Why is there the last line "This is a test"?
And I need, that if there are two or more space characters between two words, that this should not return a "row".
I only want to get the words splitted in a given string.
Does anyone have an idea?
irb(main):002:0> " This is a test ".split
=> ["This", "is", "a", "test"]
irb(main):016:0* puts " This is a test ".split
This
is
a
test
str.split(pattern=$;, [limit]) => anArray
If pattern is omitted, the value of $;
is used. If $; is nil (which is the
default), str is split on whitespace
as if ` ’ were specified.
You should do
" This is a test ".strip.each(' ') {|s| puts s.strip}
If you don't want the last "this is a test"
Because
irb>>> puts " This is a test ".strip.each(' ') {}
This is a test
The first command "puts" will be put after the each-block is excecuted.
omit the first "puts" and you are done

Resources