Slicing arrays based on relations in the data (in Ruby)

65 views Asked by At

I have arrays in this form: [1, 2, 1, 4, 5, 4, 1, 7, 7, 6] and I need to slice them into something like [[1, 2, 1], [4, 5, 4], [1], [7, 7, 6]], where breaks are determined by the absolute difference between consecutive pairs being larger than 1.

Is there in Ruby some magic that I can harness, or am I left with having to code a plain old iteration?

2

There are 2 answers

1
Stefan On BEST ANSWER

You can use Enumerable#slice_when:

a = [1, 2, 1, 4, 5, 4, 1, 7, 7, 6]
a.slice_when { |i, j| (i - j).abs > 1 }.to_a
#=> [[1, 2, 1], [4, 5, 4], [1], [7, 7, 6]]
2
Cary Swoveland On

The following will work with Ruby v1.9+:

arr = [1, 2, 1, 4, 5, 4, 1, 7, 7, 6]

arr[1..-1].each_with_object([[arr.first]]) do |e,a|
  ((a.last.last-e).abs > 1) ? a << [e] : a[-1] << e
end
  #=> [[1, 2, 1], [4, 5, 4], [1], [7, 7, 6]] 

If you need to support earlier versions, you can use reduce rather than each_with_object.