Reputation: 15010
First, what I have:
s = "1,3..5,8"
What I want:
["1", "3", "4", "5", "8"]
I found a way with as below
r = s.split(/\s?,\s?/)
=> ["10", "12..15", "17", "
r.map do |c|
if Fixnum === eval(c)
c
else
eval(c).map(&:to_s).flatten
end
end
=> ["10", "12", "13", "14", "15", "17", "18"]
Would there be a better way to achieve this?
Upvotes: 2
Views: 168
Reputation: 11882
How about this way:
s='1,2..6,10'
s.split(',').map { |e| e.strip.include?('..') ? eval("(#{e}).to_a") : e.to_i }.flatten
Upvotes: 0
Reputation: 1294
I wouldn't use eval
.
A marginally better way would be:
s = "1,3...5,8"
p s.split(',').map { |n|
if n.scan('...').empty?
n
else
Range.new(*n.split('...', 2)).to_a
end
}.flatten
# => ["1", "3", "4", "5", "8"]
EDIT: Fixed the code as suggested by @fl00r to work with multiple digit numbers.
Upvotes: 4
Reputation: 42192
s = "10,12...15,17"
s.split(',').map { |n| n['...'] ? Range.new(*n.split('...', 2)).to_a : n}.flatten
#=> ["10", "12", "13", "14", "15", "17"]
Upvotes: 1
Reputation: 83680
def magick(str)
str.split(",").map do |item|
item.scan(/(\d+)(\.+)(\d+)/)
if $1
Range.new($1.to_i, $3.to_i, $2 == "...").to_a
else
item.to_i
end
end.flatten
end
s1 = "1,3..5,8"
s2 = "1,3...5,8,20,100, 135"
magick(s1)
#=> [1, 3, 4, 5, 8]
magick(s2)
#=> [1, 3, 4, 8, 20, 100, 135]
Upvotes: 2