Cut intermittent data into continuous parts in Ruby

I have this intermittent array:

a = [1, 2, 3, 7, 8, 10, 11, 12]

I need it to be an array of contiguous arrays:

[[1, 2, 3], [7, 8], [10, 11, 12]]

I look at the original, comparing each value with the last to create new arrays:

parts = []
last = nil
a.each do |n|
  parts.push [] if last.nil? || last+1 != n
  parts.last.push n
  last = n
end

He feels dirty and non-ruby-like. I am interested in finding a clean, elegant solution.

+4
source share
7 answers

Modified version of @ hirolau's.

a = [1, 2, 3, 7, 8, 10, 11, 12]
prev = a[0] - 1
a.slice_before { |cur|  [prev + 1 != cur, prev = cur][0] }.to_a
# => [[1, 2, 3], [7, 8], [10, 11, 12]]

prev = a[0] - 1
a.slice_before { |cur|
  discontinuous = prev + 1 != cur
  prev = cur
  discontinuous
}.to_a   
# => [[1, 2, 3], [7, 8], [10, 11, 12]]
+2
source
([a[0]] + a).each_cons(2).slice_before{|k, l| k + 1 != l}.map{|a| a.map(&:last)}
# => [[1, 2, 3], [7, 8], [10, 11, 12]]
+2
source

:

http://ruby-doc.org/core-2.0.0/Enumerable.html#method-i-slice_before

a = [1, 2, 3, 7, 8, 10, 11, 12]
prev = a.first
p a.slice_before { |e|
  prev, prev2 = e, prev
  prev2 + 1 != e
}.to_a # => [[1, 2, 3], [7, 8], [10, 11, 12]]
+1

, .

a.each_cons(2).each_with_object([[ a.first ]]) do |pair, con_groups| 
  con_groups.push( [] ) if pair.reduce( :-) < -1
  con_groups.last.push( pair.last )
end
+1
arr.slice_before([]) {|elt, state|
  (elt-1 != state.last).tap{ state << elt }
}.to_a

:

state arr , slice_before. state.last . , state.last nil, .

tap state, . begin/ensure , tap . - .

, arr.

+1

, , , .

a = [1, 2, 3, 7, 8, 10, 11, 12]

a.each_with_object({ last: nil, result: [] }) do | n, memo|
  memo[:result] << [] unless memo[:last] && memo[:last] + 1 == n
  memo[:result].last << n
  memo[:last] = n
end[:result]
0

, tybro0103...

tarr = [1, 2, 3, 7, 8, 10, 11, 12]
out  = []

tarr.count.times do
  i = 0 unless tarr[0].nil? && break

  while tarr[0..i] == (0..i).map {|x| tarr[0] + x }
    i+=1
  end

  out << tarr.shift(i)
end
0

All Articles