我的范围如下:
my_range = [1297134..1328348, 1381732..1382716, 1406478..1408262, 1425452..1427966, 1607341..1609354, 1616388..1616625, 1844576..1846076, 1847450..1847672]
我喜欢遍历所有这些范围并找到最后一个范围和下一个第一个范围之间的差异,例如:
1381732 - 1328348
1406478 - 1382716
etc..
我知道有first
和last
方法,但我不知道如何说明最后一个范围和下一个范围。
会感激一些帮助。
答案 0 :(得分:8)
您可以使用Enumerable#each_cons
迭代连续元素:
my_range = [1297134..1328348, 1381732..1382716, 1406478..1408262, 1425452..1427966, 1607341..1609354, 1616388..1616625, 1844576..1846076, 1847450..1847672]
my_range.each_cons(2).map { |r1, r2| r2.first - r1.last }
#=> [53384, 23762, 17190, 179375, 7034, 227951, 1374]
答案 1 :(得分:1)
第三种方式,使用Array#zip
:
my_range = [
1297134..1328348, 1381732..1382716, 1406478..1408262, 1425452..1427966,
1607341..1609354, 1616388..1616625, 1844576..1846076, 1847450..1847672]
my_range[0..-2].zip(my_range.drop(1)).map { |r1,r2| r2.first-r1.last }
#=> [53384, 23762, 17190, 179375, 7034, 227951, 1374]
如果my_range
未排序,则步骤#1为my_range.sort_by(&:first)
。
修改强>
经过反思,我对此并不满意。它与@Stefan的答案太接近而且不太好,所以我会建议其他一些非常简单的东西:
enum = my_range.to_enum
a = []
loop do
r1 = enum.next
r2 = enum.peek
a << r2.first-r1.last
end
a
#=> [53384, 23762, 17190, 179375, 7034, 227951, 1374]
如果枚举数位于其最后一个元素,Enumerator#peek会引发StopIteration
异常。 Kernel#loop通过突破循环来处理异常。