arr = [['a',1,2],[nil,3,4],[nil,5,6],[nil,7,8],['b',9,10],[nil,11,12],[nil,13,14]]
last = nil
arr.map do |f,*rest|
if f.nil?
[last, *rest]
else
last = f
[f, *rest]
end
end
#=> [["a", 1, 2], ["a", 3, 4], ["a", 5, 6], ["a", 7, 8],
# ["b", 9, 10], ["b", 11, 12], ["b", 13, 14]]
Шаги следующие:
last = nil
enum = arr.map
#=> #<Enumerator: [["a", 1, 2], [nil, 3, 4], [nil, 5, 6], [nil, 7, 8],
# ["b", 9, 10], [nil, 11, 12], [nil, 13, 14]]:map>
f,*rest = enum.next
#=> ["a", 1, 2]
f #=> "a"
rest
#=> [1, 2]
f.nil?
#=> false
last = f
#=> "a"
[f, *rest]
#=> ["a", 1, 2]
f,*rest = enum.next
#=> [nil, 3, 4]
f.nil?
#=> true
[last, *rest]
#=> ["a", 3, 4]
f,*rest = enum.next
#=> [nil, 5, 6]
f.nil?
#=> true
[last, *rest]
#=> ["a", 5, 6]
f,*rest = enum.next
#=> [nil, 7, 8]
f.nil?
#=> true
[last, *rest]
#=> ["a", 7, 8]
и т. Д.
В качестве альтернативы,
arr.drop(1).each_with_object([arr.first]) { |a,ar|
ar << [a.first || ar.last.first, *a.drop(1)] }
#=> [["a", 1, 2], ["a", 3, 4], ["a", 5, 6], ["a", 7, 8],
# ["b", 9, 10], ["b", 11, 12], ["b", 13, 14]]