Sort a list of maps like [%{"some string" => weight}]

I would like to sort that kind of List of weighted maps:

[
  %{"this is a string" => 24},
  %{"en français" => 11}
]

into a weight ordered List of keys: ["en français", "this is a string"]

I don’t the key names in advance.

iex(72)> input = [
...(72)>   %{"this is a string" => 24},
...(72)>   %{"en français" => 11}
...(72)> ]
[%{"this is a string" => 24}, %{"en français" => 11}]
iex(73)> input |> Enum.flat_map(&Enum.to_list/1) |> Enum.sort_by(&elem(&1, 1)) |> Enum.map(&elem(&1, 0))
["en français", "this is a string"]
2 Likes

Thanks you for the fast answer! It works very fine, now I need to dig into it a little bit to understand it fully… so I won’t ask for help next time.

1 Like

A little advice I can give you to analyze @gregvaughn 's code, is to use IO.inspect().

If you run the code as is, it’s not very informative, but if you inspect in between steps, you can get a much better understanding of what’s going on.

iex> input
|> IO.inspect(label: "input")
|> Enum.flat_map(&Enum.to_list/1)
|> IO.inspect(label: "Enum.flat_map")
|> Enum.sort_by(&elem(&1, 1))
|> IO.inspect(label: "Enum.sort_by")
|> Enum.map(&elem(&1, 0))

input: [%{"this is a string" => 24}, %{"en français" => 11}]
Enum.flat_map: [{"this is a string", 24}, {"en français", 11}]
Enum.sort_by: [{"en français", 11}, {"this is a string", 24}]
["en français", "this is a string"]
4 Likes

Yes, IO.inspect is great advice.

In this specific case, I converted the given input data into a more uniform/useful data structure, a list of 2 element tuples {string, weight}. Then I sorted by the 2nd element, then I kept the 1st element.

2 Likes