我有一系列uniq号码。像这样:[1,2,3,4,7,8,10,12]。它可以是未分类的。 我需要的是获得这个数组的间隔:
intervals_for [1,2,3,4,7,8,10,12]
#=> "1-4, 7-8, 10,12"
我有自己的解决方案:
def intervals_for(array)
array.sort!
new_array = []
array.each do |a|
if new_array.last and a == new_array.last.last+1
new_array.last << a
else
new_array << [a]
end
end
new_array.map{|a| a.size > 1 ? "#{a.first}-#{a.last}" : a.first}.join(", ")
end
但我认为这里的某处是更干净的解决方案
答案 0 :(得分:2)
这是我的,使用ver 1.9.1
def torange(a)
r=[];s=a[0]
a.uniq.sort!.each_cons(2) do |a|
r<<[s,a[0]] and s=a[1] if a[1]-a[0]!=1
end
left=a.index(s)
r<<[a[left..-1][0],a[left..-1][-1]]
end
torange([1,2,3,4,7,8,10,12]).each do |x|
puts x[0]==x[1] ? "#{x[0]}" : "#{x[0]}-#{x[1]}"
end
输出
$ ruby test.rb
1-4
7-8
10
12
答案 1 :(得分:1)
这是我的单行:
array = [-10, -9, -1, 0, 1, 2, 3, 4, 10, 11, 15, 133]
array.uniq.sort.inject([]){ |a, e| a[-1] && a[-1].last && a[-1].last == e-1 ? a[-1] = (a[-1].first..e) : a << (e..e); a }
#=> [-10..-9, -1..4, 10..11, 15..15, 133..133]
小monkeypatchng
class Array
def.collect_to_ranges
self.uniq.sort.inject([]){ |a, e| a[-1] && a[-1].last && a[-1].last == e-1 ? a[-1] = (a[-1].first..e) : a << (e..e); a }
end
end
array = [1,2,3,4,5,6,7,8, 10]
array.collect_to_ranges
#=> [1..8, 10..10]
答案 2 :(得分:0)
这个是递归的,感觉它可能会更好......但
arr = [1,2,3,4,7,8,10,12]
def intervals(arr)
return arr if arr.size == 0 || arr.size == 1
int = [arr.shift]
while int.last + 1 == arr.first
int << arr.shift
end
( int.size == 1 ? int : ["#{int.first}-#{int.last}"] ) + intervals(arr)
end
p intervals(arr)