Not sure it has any performance impact, but just FYI since Elixir does bitstring comparison byte by byte and your city keys are going to be unique strings (enforced by using them as keys for a map) you don't gain anything by comparing against the key versus comparing against the generated string in this function:
keys_strings =
Map.keys(combined_map)
|> Enum.map(fn key ->
{min_temp, count, sum, max_temp} = Map.get(combined_map, key)
{key,
"#{key}=#{min_temp / 10}/#{:erlang.float_to_binary(sum / (count * 10), decimals: 1)}/#{max_temp / 10}"}
end)
# sort the strings by city/key then discard the key, keep the output
sorted_strings = Enum.sort_by(keys_strings, &elem(&1, 0)) |> Enum.map(&elem(&1, 1))
and you might get a tiny performance improvement by avoiding a second Enum.map call.
Not sure it has any performance impact, but just FYI since Elixir does bitstring comparison byte by byte and your city keys are going to be unique strings (enforced by using them as keys for a map) you don't gain anything by comparing against the key versus comparing against the generated string in this function:
and you might get a tiny performance improvement by avoiding a second
Enum.mapcall.