2

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?

4 Answers 4

4

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Why would not you use eval? Is there a reason for this or just a personal way of doing it?
see the following question: stackoverflow.com/questions/1902744/…
what if numbers are two digits? s=1,3...5,8,11? And what if ranges are two-dotted and three-dotted? s=1..3, 5...7, 20
good catch @fl00r, thanks. Regarding the number of dots, the original question asked for two.
2
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]

Comments

1
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"]

2 Comments

12...15 in Ruby shouldn't return 15
@fl00r true but the original question was written with three-dots and expected to return 15.
0

How about this way:

s='1,2..6,10'

s.split(',').map { |e| e.strip.include?('..') ? eval("(#{e}).to_a") : e.to_i }.flatten

1 Comment

i also program in javascript and there eval is evil, don't know about ruby but there must be also drawback's

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.