How to puts arguments in one line? - ruby

I want to make it like in Python, 4 example:
print(
foobar,
footree,
foodrink
)
and it will be print in one line:
>>> "foobar, footree, foodrink"
In Ruby with the same code:
puts foobar,
footree,
foodrink
>>> "foobar"
... "footree"
... "foodrink"
Yes, I can do it with print, like this, but it looks ugly:
puts "foobar" +
"foobar" +
"foobar" +
>>> "foobar, footree, foodrink"
Thx in advance!
Edited. Now I have the following "Align the arguments of a method call if they span more than one line" and in terminal it output from a new line, I need it in one line.

You have to do
puts "#{foobar}, #{footree}, \
#{foodrink}"

>> a, b = "bar", "tree"
>> puts [a, b].join(", ")
bar, tree
or print:
>> print a, ", ", b, "\n"
bar, tree

I'm making some assumptions about your various data types based on limited information given in your example, but the closest syntax I can come up with is using an array([]) along with p and join like so:
foobar = "foobar"
footree = "footree"
foodrink = "foodrink"
p [
foobar,
footree,
foodrink
].join(" ")
#=> "foobar footree foodrink"

Related

Reversing characters in a string regardless of the number of spaces - Ruby

This question is from codewars
Complete the function that accepts a string parameter, and reverses each word in the string. All spaces in the string should be retained.
Here is my code that only works for a string with single spaces, but I can't seem to figure out how to add/subtract anything to it to make it work for a string with more than one space in-between each word.
def reverse_words(str)
str.split(" ").map(&:reverse!).join(" ")
end
Examples given:
('The quick brown fox jumps over the lazy dog.'), 'ehT kciuq nworb xof spmuj revo eht yzal .god')
('apple'), 'elppa')
('a b c d'), 'a b c d')
('double spaced words'), 'elbuod decaps sdrow')
I think the easiest option to tackle this is by using a regex.
def reverse_words(str)
str
.scan(/(\s*)(\S+)(\s*)/)
.map { |spacer1, word, spacer2| spacer1 + word.reverse + spacer2 }
.join
end
This searches the string for zero or more whitespaces captured by the first group. Followed by one or more non-whitespaces, captured by the second group. Followed by zero or more whitespaces captured in the third group. Mapping over the resulting array we can combine the spacers back with the reversed word and join the whole thing together.
The above results in the following output:
reverse_words('The quick brown fox jumps over the lazy dog.')
#=> "ehT kciuq nworb xof spmuj revo eht yzal .god"
reverse_words('apple')
#=> "elppa"
reverse_words('a b c d')
#=> "a b c d"
reverse_words('double spaced words')
#=> "elbuod decaps sdrow"
reverse_words(' foo bar ')
#=> " oof rab "
References:
String#scan
Array#map
Array#join
Regular expressions in Ruby
Here you go:
irb(main):023:0> 'double spaced words'.split(//).reverse.join
=> "sdrow decaps elbuod"
Pass regexp so String#split does not omit spaces. There are similar examples in docs
Just to play with recursion, even if Johan Wentholt answer is the best so far:
def part(string)
if string.count(" ") > 0
ary = string.partition(/\s{1,}/)
last = ary.pop
ary << part(last)
ary.flatten
else string
end
end
part(string).map(&:reverse).join
Well,
f = " Hello im the world"
ff = f.split #=> ["Hello", "im", "the", "world"]
ff.each do |a|
a.reverse! #=> ["olleH", "mi", "eht", "dlrow"]
end
ff.join! #=> "olleH mi eht dlrow"

Ruby .times method returns variable instead of output

In order to pass an rspec test, I need to get a simple string to be returned "num" amount of times. I've been googling and it seems the .times method should help. In theory from what I can see:
num = 2
string = "hello"
num.times do
string
end
...Should work? But the output continues to return as "2", or whatever "num" is equal to. I can get it to "puts 'hello'" twice, but it still returns "2" after printing "hellohello".
Also tried
num.times { string }
Am I missing something fundamental about the .times method, here? Or should I be going about this another way?
times will repeat the execution of the block: string will be interpreted twice, but the value won't be used for anything. num.times will return num. You can check it in a Ruby console :
> 2.times{ puts "hello" }
hello
hello
=> 2
You don't need a loop, you need concatenation:
string = "hello"
string + string
# "hellohello"
string + string + string
# "hellohellohello"
Or just like with numbers, you can use multiplication to avoid multiple additions :
string * 3
# "hellohellohello"
num = 2
string * num
# "hellohello"
If you need a list with 2 string elements, you can use :
[string] * num
# ["hello", "hello"]
or
Array.new(num) { string }
# ["hello", "hello"]
If you want to join the strings with a space in the middle :
Array.new(num, string).join(' ')
# "hello hello"
Just for fun, you could also use :
[string] * num * " "
but it's probably not really readable.
Is this the behavior you're looking for?
def repeat(count, text)
text * count
end
repeat(2, "hello") # => "hellohello"
(No steps were taken to defend against bad input)

How do I use 'gsub' to make multiple substiuttions?

I have a string that only contains one number on either side of "-", like:
"1-3"
I want to get a result like
"01-03"
If the string had two numbers on one side of the dash like:
"1-10"
then I don't want to make any substitutions. I could do a gsub expression like
str.gsub!(/(^|[^\d]])\d[[:space:]]*\-[[:space:]]*\d([^\d]|$)/, '\1')
but I'm not clear how to do it if there are multiple (e.g. two) things to substitute.
You could probably get away with this:
def dashreplace(str)
str.sub(/\b(\d)\-(\d)\b/) do |s|
'%02d-%02d' % [ $1.to_i, $2.to_i ]
end
end
dashreplace('1-2')
# => "01-02"
dashreplace('1-20')
# => "1-20"
dashreplace('99-1,2-3')
# => "99-1,02-03"
Is there really a need to use regex here, at all? Seems like an over-complication to me. Assuming you know the string will be in the format: <digits><hyphen><digits>, you could do:
def pad_digits(string)
left_digits, right_digits = string.split('-')
if left_digits.length > 1 || right_digits.length > 1
string
else
"%02d-%02d" % [left_digits, right_digits]
end
end
pad_digits("1-3") # => "01-03"
pad_digits("1-10") # => "1-10"
This is a variant of #TomLord's answer.
def pad_single_digits(str)
str.size > 3 ? str : "0%d-0%d" % str.split('-')
end
pad_single_digits "1-3" #=> "01-03"
pad_single_digits "1-10" #=> "1-10"
"0%s-0%s" also works.
You can do:
def nums(s)
rtr=s[/^(\d)(\D+)(\d)$/] ? '0%s%s0%s' % [$1,$2,$3] : s
end

no Errors but no Result

I need to find each occurrence of "$" and change it to a number using a count. eg str = "foo $ bar $ foo $ bar $ * run code here * => "foo 1 bar 2 foo 3 bar 4
It feels like this should be a lot easier than i'm making it out to be. Here's my code:
def counter(file)
f = File.open(file, "r+")
count = 0
contents = f.readlines do |s|
if s.scan =~ /\$/
count += 1
f.seek(1)
s.sub(/\$/, count.to_s)
else
puts "Total changes: #{count}"
end
end
end
However I'm not sure if I'm meant to be using .match, .scan, .find or whatever else.
When i run this it doesn't come up with any errors but it doesn't change anything either.
Your syntax for scan is incorrect and it should throw error.
You can try something along this line:
count = 0
str = "foo $ bar $ foo $ bar $ "
occurences = str.scan('$')
# => ["$", "$", "$", "$"]
occurences.size.times do str.sub!('$', (count+=1).to_s) end
str
# => "foo 1 bar 2 foo 3 bar 4 "
Explanation:
I am finding all occurences of $ in the string, then I am using sub! in iteration as it replaces only the first occurrence at a time.
Note: You may want to improve scan line by using regex with boundary match instead of plain "$" as it will replace $ even from within words. Eg: exa$mple will also get replace to something like: exa1mple
Why your code is not throwing error?
If you read the description about readlines, you will find:
Reads the entire file specified by name as individual lines, and
returns those lines in an array.
As it reads the entire file at once there is no value passing block along this method. Following example will make it more clear:
contents = f.readlines do |s|
puts "HELLO"
end
# => ["a\n", "b\n", "c\n", "d\n", "asdasd\n", "\n"] #lines of file f
As you can see "HELLO" never gets printed, showing the block code is never executed.

How do I print Arrays?

I have the array:
example = ['foo', 'bar', 'quux']
I want to iterate over it and print it so it comes out like: foo bar quux, not ['foo', 'bar', 'quux'] which would be the case if I used each or for.
Note: I can't just do: example[0];example[1], etc. because the length of the array is variable.
How do I do this?
Here:
puts array.join(' ') # The string contains one space
example.join(" ") #=> foo bar quux.
If you used each to print, it would work fine:
example.each {|item| print item; print " " } #=> foo bar quux
However, if what you want is a string with the items separated by spaces, that's what the join method is for:
example.join(' ') #=> "foo bar quux"
I suspect your problem is that you're confusing printing with iterating, as each just returns the original array — if you want things printed inside of it, you need to actually print like I did in the example above.
if they may be printed underneath each other just use
puts example
=>
foo
bar
quux
otherwise use the solutions from the other answers
puts example.join(" ")

Resources