Reputation: 3908
I would love to set three variables a
, b
and c
from a single gets
line. For example, user entering a line of space-delimited numbers "1 2.2 -3.14"
would set a
to 1
, b
to 2.2
and c
to -3.14
respectively. I achieve this like so:
input = gets.strip.split
a,b,c = input[0].to_f,input[1].to_f,input[2].to_f
Is there a more elegant way to assign array entries to a range of variables? Perhaps something with a splat and a cycle?
input.each {|entry| *(a..z) = entry }
Upvotes: 1
Views: 63
Reputation: 110685
str = "scan may be 1 useful if 2.2 the string may contain -3.14 other stuff"
arr = []
str.scan(/-?\d*(?:\d|\.\d|\d\.)\d*/) { |s| arr << s.to_f }
arr #=> [1.0, 2.2, -3.14]
The regex extracts the embedded numbers that have zero or one decimal points.
Considering that you are using gets
to obtain str
, I've chosen to use arr =
rather than a,b,c =
so I can make sure the correct number of floats have been returned:
if arr.size == 3
a,b,c = arr
else
<raise exception>
end
With v1.9+ you could save a line (just saying, not advocating) by using Object#tap:
arr = [].tap { |a| str.scan(/-?\d*(?:\d|\.\d|\d\.)\d*/) { |s| a << s.to_f } }
Upvotes: 0
Reputation: 37409
a,b,c = "1 2.2 -3.14".split.map(&:to_f)
# => [1.0, 2.2, -3.14]
b
# => 2.2
Upvotes: 4