How do I unify 2 structures?

Guys, can I join these 2 structures into a single one?
Ex:

a = 
[
%{name: "Test 1"},
%{name: "Test 2"},
%{name: "Test 3"}
]
b = 
[
%{local: "EUA"},
%{local: "BRAZIL"}
%{local: "CHN"}
}

The idea is to stay that way

[
%{name: "Test 1", local: "EUA"},
%{name: "Test 2", local: "BRAZIL"},
%{name: "Test 3", local: "CHN"}
]

If the lists have the same size, and the same order, You might try Enum.zip and Map.merge…

not tested…

a
|> Enum.zip(b)
|> Enum.map(fn {ela, elb} -> 
  Map.merge(ela, elb)
end)

BTW They are not structs, but maps.

3 Likes

Thank you, it helped me a lot

Or

for i <- 0..length(a) do
  Map.merge(
    Enum.at(a, i), 
    Enum.at(b, i)
  )
end

This seems heavy

Might be :slight_smile: I haven’t tested the performance. But the docs for Enum do warn about this:

The functions in this module work in linear time. This means that, the time it takes to perform an operation grows at the same rate as the length of the enumerable

@gilbertosj You can do it in one, simple line. :smiling_imp:

iex> a = [%{name: "Test 1"}, %{name: "Test 2"}, %{name: "Test 3"}]
iex> b = [%{local: "EUA"}, %{local: "BRAZIL"}, %{local: "CHN"}]
iex> Enum.zip_with(a, b, &Map.merge/2)
[
  %{local: "EUA", name: "Test 1"},
  %{local: "BRAZIL", name: "Test 2"},
  %{local: "CHN", name: "Test 3"}
]
5 Likes

Oh, yes, Enum.zip_with… :smiley:

Using comprehensions is probably not a good option for this, because you cannot easily iterate over two items in sync, and have to resort to inefficiently looking up the index as you discovered. If you wanted to do it without Enum, recursion would be a better solution - but that’s what zip_with is doing anyway, so you may as well use that :slight_smile:

1 Like