Ruby 将数组分成连续数的范围
我正在尝试创建一个Ruby函数,该函数将唯一数字数组转换为连续数字的范围Ruby 将数组分成连续数的范围,ruby,arrays,algorithm,Ruby,Arrays,Algorithm,我正在尝试创建一个Ruby函数,该函数将唯一数字数组转换为连续数字的范围 [1, 2, 3, 5, 6, 8, 9] => [(1..3), (5..6), (8..9)] 这似乎不太难,但我想知道是否有更好的方法。这里有一个答案,可以回答您提出的同一个问题。链接代码所做的工作比您需要的要多一些(数字不需要排序或连续),但它可以做到这一点。或者,您可以使用@NewAlexandria建议的代码: class Array def to_ranges compact.sor
[1, 2, 3, 5, 6, 8, 9] => [(1..3), (5..6), (8..9)]
这似乎不太难,但我想知道是否有更好的方法。这里有一个答案,可以回答您提出的同一个问题。链接代码所做的工作比您需要的要多一些(数字不需要排序或连续),但它可以做到这一点。或者,您可以使用@NewAlexandria建议的代码:
class Array
def to_ranges
compact.sort.uniq.inject([]) do |r,x|
r.empty? || r.last.last.succ != x ? r << (x..x) : r[0..-2] << (r.last.first..x)
end
end
end
类数组
def至_范围
compact.sort.uniq.inject([])do | r,x|
r、 空的r、 last.last.suck!=x?这是我不久前在处理IP地址范围时写的:
class Array
# [1,2,4,5,6,7,9,13].to_ranges # => [1..2, 4..7, 9..9, 13..13]
# [1,2,4,5,6,7,9,13].to_ranges(true) # => [1..2, 4..7, 9, 13]
def to_ranges(non_ranges_ok=false)
self.sort.each_with_index.chunk { |x, i| x - i }.map { |diff, pairs|
if (non_ranges_ok)
pairs.first[0] == pairs.last[0] ? pairs.first[0] : pairs.first[0] .. pairs.last[0]
else
pairs.first[0] .. pairs.last[0]
end
}
end
end
if ($0 == __FILE__)
require 'awesome_print'
ary = [1, 2, 4, 5, 6, 7, 9, 13, 12]
puts ary.join(', ')
ap ary.to_ranges
ary = [1, 2, 4, 8, 5, 6, 7, 3, 9, 11, 12, 10]
puts ary.join(', ')
ap ary.to_ranges
end
将true
传递到传递到_ranges
时,它不会将单个元素转换为一个元素范围。这是如何使用的
比什么好?你还没有发布你的解决方案,当你要求提供代码时,你需要提供你已经尝试过的答案。我们需要知道你正在付出一些努力,而不仅仅是在寻找代码。这是一个很好的方法!虽然我很好奇你什么时候不希望参数为真,但我有时需要将数组缩小为范围和值。这不仅仅对整数有用;正如我在代码中所说,我使用它将IP号码转换为网络范围和单个IP。其他时候我只是想要一个靶场,工作得很有魅力。我爱你,谢谢你为我节省了几分钟的算法时间。我非常喜欢这个解决方案。它似乎已经进入了文档:嗯。。。事实上,我认为NewAlexandria只是把你链接中的代码复制到了问题中。。。所以,从技术上讲,这是你建议的代码。。。
ar = [1, 2, 3, 5, 6, 8, 9]
prev = ar[0]
p ar.slice_before { |e|
prev, prev2 = e, prev
prev2 + 1 != e
}.map{|a| a[0]..a[-1]}
# >> [1..3, 5..6, 8..9]
ar = [1, 2, 3, 5, 6,7, 8, 9,11]
prev = ar[0]
p ar.slice_before { |e|
prev, prev2 = e, prev
prev2 + 1 != e
}.map{|a| a[0]..a[-1]}
# >> [1..3, 5..9, 11..11]