I have two arrays:
a = [nil, 1, nil]
b = [4, 5, 6]
And i want to replace nil elements from first array with related elements from second array:
[4, 1, 6]
What is the best way to do it?
You can use
a.zip(b).map(&:compact).map(&:first) #=> [4, 1, 6]
Steps:
a.zip(b)
#=> [[nil, 4], [1, 5], [nil, 6]]
a.zip(b).map(&:compact)
#=> [[4], [1, 5], [6]]
a.zip(b).map(&:compact).map(&:first)
#=> [4, 1, 6]
By virtue of Array#compact this approach removes nil elements only from the zipped pairs i.e. false elements are not removed.
a.zip(b).map { |e| e.compact[0] } 2 iterations instead of 3 :)Another way is by using a block when creating this new array like so:
a = [nil, 1, nil]
b = [4, 5, 6]
Array.new(a.size) { |i| a[i].nil? ? b[i] : a[i] }
#=> [4, 1, 6]
Still another variant:
a.zip(b).map{|a, b| [*a, *b].first}
# => [4, 1, 6]
This distinguishes nil from false, as expected. But note that you cannot use this with elements that are broken by to_a, such as hashes.