Reputation: 6064
I have an array like
A=[[a,x,y,z],[nil,e,f,d],[nil,k,j,u],[nil,w,p,k],[b,x,y,z],[nil,e,f,d],[nil,k,j,u],[nil,w,p,k]]
Result
A=[[a,x,y,z],[a,e,f,d],[a,k,j,u],[a,w,p,k],[b,x,y,z],[b,e,f,d],[b,k,j,u],[b,w,p,k]]
You might be noticing that first character of the first array is replacing the upcoming nil value until first character of the first array is b and then nil values are replaced with b.
This one I have achieved through iterating the array and writing the if condition and storing the first character somewhere and then by comparing the first character while I am iterating. But I don't still don't find a ruby way of doing this. Can someone help me here
Upvotes: 1
Views: 133
Reputation: 80065
A = [['a',1,2],[nil,3,4],[nil,5,6],[nil,7,8],['b',9,10],[nil,11,12],[nil,13,14]]
A.each_cons(2){|first, last| last[0] ||= first[0] }
last[0] ||= first[0]
means something like "Give last[0] the value of first[0], unless it already has a value (not nil or false)".
Upvotes: 3
Reputation: 110675
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]]
The steps are as follows:
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]
and so on.
Alternatively,
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]]
Upvotes: 2