最后范围与下一个第一范围之间的差异

时间:2014-04-30 15:20:44

标签: ruby arrays range

我的范围如下:

my_range =  [1297134..1328348, 1381732..1382716, 1406478..1408262, 1425452..1427966, 1607341..1609354, 1616388..1616625, 1844576..1846076, 1847450..1847672]

我喜欢遍历所有这些范围并找到最后一个范围和下一个第一个范围之间的差异,例如:

1381732 - 1328348
1406478 - 1382716
etc..

我知道有firstlast方法,但我不知道如何说明最后一个范围和下一个范围。

会感激一些帮助。

2 个答案:

答案 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通过突破循环来处理异常。