我希望在Ruby中将一个带间隙的数字数组转换为一个多个范围的数组。
每个范围应确定顺序中的差距:
[1,2,3,5,6,8,9,10,11,12]预期结果将是:
[1-3, 5-6, 8-12]我还没有想出任何解决这个问题的好主意。我该怎么解决这个问题?
发布于 2013-12-30 20:47:06
我将按照下面的方式使用Enumerable#slice_before:
a = [1,2,3,5,6,8,9,10,11,12]
prev = a[0]
p a.slice_before { |e|
prev, prev2 = e, prev
prev2 + 1 != e
}.map{|b,*,c| c ? (b..c) : b }
# >> [1..3, 5..6, 8..12]发布于 2013-12-31 03:42:00
a = [1,2,3,5,8,9,10,11,12]
b = [a.first-1] + (a.first..a.last).to_a - a + [a.last + 1]
# => [0, 4, 6, 7, 13]
b.each_cons(2).with_object([]) {|(i,j), c| c << (i+1..j-1) if j > i+1}
# => [1..3, 5..5, 8..12] 或者,
b = [a.first] + ((a.first..a.last).to_a - a).flat_map {|e| [e-1,e+1]}+[a.last]
# => [1, 3, 5, 5, 7, 6, 8, 12]
b.each_slice(2).map {|f,l| l >= f ? f..l : nil}.compact
# => [1..3, 5..5, 8..12]注:b.each_slice(2).to_a # => [[1, 3], [5, 5], [7, 6], [8, 12]]
发布于 2013-12-30 20:51:33
另一种解决办法是:
class Array
def to_range_array
res = [ Range.new(first,first) ]
self[1..-1].sort.each{|item|
if res.last.max == (item -1)
res << Range.new(res.pop.min, item)
else
res << Range.new(item, item)
end
}
res
end
end
array = [ 1,2,3,5,6,8,9,10,11,12 ]
p array.to_range_array #[1..3, 5..6, 8..12]我的假设是:
[ 9,10,11,12, 1,2,3,5,6,8]应该返回与[ 1,2,3,5,6,8,9,10,11,12 ]相同的结果。如果没有排序命令,就会得到[9..12, 1..3, 5..6, 8..8]。8..8)。https://stackoverflow.com/questions/20847212
复制相似问题