我试图解析一个由","
加入的数字和范围字符串,并将其转换为一个数字数组。我把它作为输入:"1,3,6-8,5"
,并且希望有一个类似于这样的数组:[1,3,5,6,7,8]
。
我只能在没有范围的情况下这样做:
"12,2,6".split(",").map { |s| s.to_i }.sort #=> [2, 6, 12]
在一定范围内,我做不到:
a = "12,3-5,2,6"
b = a.gsub(/-/, "..") #=> "12,3..5,2,6"
c = b.split(",") #=> ["12", "3..5", "2", "6"]
d = c.sort_by(&:to_i) #=> ["2", "3..5", "6", "12"]
e = d.split(",").map { |s| s.to_i } #>> Error
我该怎么做?
我还在考虑在map
中使用splat运算符,但是splat不接受像[*(3..5)]
这样的字符串。
发布于 2018-04-08 15:48:16
"12,3-5,2,6".
gsub(/(\d+)-(\d+)/) { ($1..$2).to_a.join(',') }.
split(',').
map(&:to_i)
#⇒ [12, 3, 4, 5, 2, 6]
发布于 2018-04-08 13:42:19
"1,3,6-8,5".split(',').map do |str|
if matched = str.match(/(\d+)\-(\d+)/)
(matched[1].to_i..matched[2].to_i).to_a
else
str.to_i
end
end.flatten
或
"1,3,6-8,5".split(',').each_with_object([]) do |str, output|
if matched = str.match(/(\d+)\-(\d+)/)
output.concat (matched[1].to_i..matched[2].to_i).to_a
else
output << str.to_i
end
end
还是严格的
RANGE_PATTERN = /\A(\d+)\-(\d+)\z/
INT_PATTERN = /\A\d+\z/
"1,3,6-8,5".split(',').each_with_object([]) do |str, output|
if matched = str.match(RANGE_PATTERN)
output.concat (matched[1].to_i..matched[2].to_i).to_a
elsif str.match(INT_PATTERN)
output << str.to_i
else
raise 'Wrong format given'
end
end
发布于 2018-04-08 17:58:20
"1,3,6-8,5".split(',').flat_map do |s|
if s.include?('-')
f,l = s.split('-').map(&:to_i)
(f..l).to_a
else
s.to_i
end
end.sort
#=> [1, 3, 5, 6, 7, 8]
https://stackoverflow.com/questions/49718344
复制相似问题