Merge two list of same length, empty values in one list filled with values from 2nd

I got two lists x and y, both contain 10 items.
In first list some values are empty, but list 2 contains those values and visa versa, i.e
list x
[“one”]
[]
[“three”]
[“four”]
[]

list y
[]
[“two”]
[]
[]
[“five”]

new list z should contain all values [“one”][“two”][“three”][“four”][“five”], how can I merge them ?

defmodule Example do
  def sample([], []), do: []
  def sample([head | tail], [[] | tail2]), do: [head | sample(tail, tail2)]
  def sample([[] | tail], [head2 | tail2]), do: [head2 | sample(tail, tail2)]
end

first = [["one"], [], ["three"], ["four"], []]
second = [[], ["two"], [], [], ["five"]]

Example.sample(first, second)
# [["one"], ["two"], ["three"], ["four"], ["five"]]
5 Likes

I would maybe start with List.zip/1 which gives you a result like:

[
  {"one", ""},
  {"", "two"},
  {"three", ""},
  ...
]

And then you Enum.map/2 over it with a custom function that checks the tuple and returns the value.

5 Likes

Snap - you saved me typing…

1 Like

I think it can also be done in one pass, with recursion, keeping the order of the list…

defmodule Koko do
  def run [], [], acc do
    Enum.reverse acc
  end

  def run [h1|t1], [h2|t2], acc do
    new_acc = [(if not Enum.empty?(h1), do: h1, else: h2) |acc]
    run t1, t2, new_acc
  end
end
x = [["one"], [], ["three"], ["four"], []]
y = [[], ["two"], [], [], ["five"]]
Koko.run x, y, []
[["one"], ["two"], ["three"], ["four"], ["five"]]

Update: Oh, it looks like @Eiji already provided this solution :slight_smile:

1 Like

I would go with: :lists.zipwith(fn [], [v] -> [v] ; [v], [] -> [v] end, list_a, list_b).

2 Likes

Thank you!!!