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?

oldergod
  • 15,033
  • 7
  • 62
  • 88

4 Answers4

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.

Jakobinsky
  • 1,294
  • 8
  • 11
  • Why would not you use eval? Is there a reason for this or just a personal way of doing it? – oldergod Apr 11 '12 at 08:25
  • see the following question: http://stackoverflow.com/questions/1902744/when-is-eval-in-ruby-justified – Jakobinsky Apr 11 '12 at 08:29
  • 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` – fl00r Apr 11 '12 at 09:15
  • good catch @fl00r, thanks. Regarding the number of dots, the original question asked for two. – Jakobinsky Apr 11 '12 at 09:54
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]
fl00r
  • 82,987
  • 33
  • 217
  • 237
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"]
peter
  • 41,770
  • 5
  • 64
  • 108
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
DaveShaw
  • 52,123
  • 16
  • 112
  • 141
Zack Xu
  • 11,505
  • 9
  • 70
  • 78
  • i also program in javascript and there eval is evil, don't know about ruby but there must be also drawback's – peter Apr 11 '12 at 20:05