I need to add consecutive numbers to a new array and, if it is not a consecutive number, add only that value to a new array:
old_array = [1, 2, 3, 5, 7, 8, 9, 20, 21, 23, 29]
I want to get this result:
new_array = [
[1,2,3],
[5],
[7,8,9]
[20,21]
[23],
[29]
]
Is there an easier way to do this?
Method 1 (Use Sorting) 1) Sort all the elements. 2) Do a linear scan of the sorted array. If the difference between the current element and the next element is anything other than 1, then return false. If all differences are 1, then return true.
array. groupBy(callback) accepts a callback function that's invoked with 3 arguments: the current array item, index, and the array itself. The callback should return a string: the group name where you'd like to add the item.
Approach: Initialize count = 0 and traverse the array from arr[0] to arr[n – 2]. If the current element is equal to the next element in the array then increment the count. Print the count in the end.
A little late to this party but:
old_array.slice_when { |prev, curr| curr != prev.next }.to_a
# => [[1, 2, 3], [5], [7, 8, 9], [20, 21], [23], [29]]
This is the official answer given in RDoc (slightly modified):
actual = old_array.first
old_array.slice_before do
|e|
expected, actual = actual.next, e
expected != actual
end.to_a
A couple other ways:
old_array = [1, 2, 3, 5, 7, 8, 9, 20, 21, 23, 29]
#1
a, b = [], []
enum = old_array.each
loop do
b << enum.next
unless enum.peek.eql?(b.last.succ)
a << b
b = []
end
end
a << b if b.any?
a #=> [[1, 2, 3], [5], [7, 8, 9], [20, 21], [23], [29]]
#2
def pull_range(arr)
b = arr.take_while.with_index { |e,i| e-i == arr.first }
[b, arr[b.size..-1]]
end
b, l = [], a
while l.any?
f, l = pull_range(l)
b << f
end
b #=> [[1, 2, 3], [5], [7, 8, 9], [20, 21], [23], [29]]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With