Arrays Ruby组非零数字和顺序时间

Arrays Ruby组非零数字和顺序时间,arrays,ruby,grouping,nmatrix,Arrays,Ruby,Grouping,Nmatrix,我有这样一个项目数组:[DateTime,value]。我想对满足以下条件的项目进行分组: 三项或三项以上的序列 项目包含大于0的值 时间是连续的(增加1秒) 我想得到满足这些条件的序列的开始和结束的索引 例如 应返回: [ [0,2] ] 我看了一下,但我不知道如何进行顺序比较,以达到我的目的 现在我有一个大循环,可以做很多比较——有更好的方法吗 t = Time.now a = [ [t + 0, 1], [t + 1, 1], [t + 2, 1], [t + 3,

我有这样一个项目数组:
[DateTime,value]
。我想对满足以下条件的项目进行分组:

  • 三项或三项以上的序列
  • 项目包含大于0的值
  • 时间是连续的(增加1秒)
我想得到满足这些条件的序列的开始和结束的索引

例如

应返回:

[ [0,2] ]
我看了一下,但我不知道如何进行顺序比较,以达到我的目的

现在我有一个大循环,可以做很多比较——有更好的方法吗

t = Time.now
a = [
  [t + 0, 1],
  [t + 1, 1],
  [t + 2, 1],
  [t + 3, 0],
  [t + 4, 1],
  [t + 5, 1],
  [t + 16, 1],
  [t + 17, 1],
]

a
.each_with_index
.chunk_while{
  |(x, i), (y, j)|
  x[1].positive? and
  y[1].positive? and
  x[0].to_i.next == y[0].to_i
}
.select{|chunk| chunk.length >= 3}
.map{|chunk| [chunk.first[1], chunk.last[1]]}
# => [[0, 2]]
可以用双通道替代:

select { |a| a.last - a.first >= 2 }.map { |a| [a.first, a.last] }

解释你所说的“时间是连续的”是什么意思。不清楚。“顺序”是否意味着它们正好相隔1秒?@sawa,stefan抱歉,是的,顺序意味着时间相隔1秒。@stefan编辑为“顺序”1)索引
i
j
来自
的每个带有
索引的代替
&
@Stefan我知道我可以用
\uu
,但为了清楚起见,我用了
I
j
。您可以很容易地看到它们是索引。这有助于以后阅读
chunk.first[1],chunk.last[1]
。它说明了
[1]
的含义。而且使用
也没有什么错。人们倾向于将控制序列与返回值的东西区分开来,但这种想法在Ruby中没有意义。Ruby中的每个表达式都有一个返回值。在这样的上下文中,使用像
这样的普通单词更容易阅读。感谢您的清晰解释和涵盖不同的ruby版本!
t = Time.now
arr = [[t+ 0, 1], [t+ 1, 1], [t+ 2, 1], [t+ 3, 0], [t+ 4, 1], [t+ 5, 1], [t+16, 1],
       [t+18, 1], [t+19, 1], [t+20, 1], [t+21, 1], [t+30, 1]]
  #=> [[2018-11-06 10:11:52 -0800, 1], [2018-11-06 10:11:53 -0800, 1],...,
  #    [2018-11-06 10:12:22 -0800, 1]]

arr.each_index.
    slice_when { |i,j| arr[i].last.zero? || arr[i-1].last.zero? ||
      (arr[i].first - arr[i-1].first > 1) }.
    each_with_object([]) { |a,b| b << [a.first, a.last] if a.last-a.first >= 2 }
  #=> [[0, 2], [7, 10]]
arr.each_index.
    slice_before { |i| i > 0 &&
      (arr[i].last.zero? || arr[i-1].last.zero? || (arr[i].first - arr[i-1].first > 1)) }.
    each_with_object([]) { |a,b| b << [a.first, a.last] if a.last-a.first >= 2 }
enum = arr.each_index.slice_before {|i| i > 0 &&
  (arr[i].last.zero? || arr[i-1].last.zero? || (arr[i].first - arr[i-1].first > 1)) }
  #=> => #<Enumerator: #<Enumerator::Generator:0x0000000001948d50>:each>
enum.to_a
  #=> [[0, 1, 2], [3], [4, 5], [6], [7, 8, 9, 10], [11]]
each_with_object([]) { |a,b| b << [a.first, a.last] if a.last-a.first >= 2 }
select { |a| a.last - a.first >= 2 }.map { |a| [a.first, a.last] }