#elixir
#elixir
Вопрос:
Я хочу отсортировать приведенный ниже список объектов так, чтобы возвращаемый список содержал объект в порядке предоставленного списка ключей. например:
Given object list:
my_list==> [{"ipnetworkaddress", [], "33.33.123.148"}, {"httpbrowsertype", [], "Mozilla"}, {"hostname", [], "example.com"}]
Given order list having object first attribute for criteria:
ordered_keys ===> ["hostname", "httpbrowsertype", "ipnetworkaddress"]
Desired result ==> [{"hostname", [], "example.com"}, {"httpbrowsertype", [], "Mozilla"}, {"ipnetworkaddress", [], "33.33.123.148"} ]
Ответ №1:
Enum.sort_by/3
ваш друг.
Enum.sort_by(my_list, amp;Enum.find_index(keys, fn e ->
e == elem(amp;1, 0)
end), amp;<=/2)
#⇒ [
# {"hostname", [], "example.com"},
# {"httpbrowsertype", [], "Mozilla"},
# {"ipnetworkaddress", [], "33.33.123.148"}
# ]
Это не самое эффективное решение, но самое чистое, и для относительно коротких списков оно достаточно хорошо.
Для каждого элемента в списке, подлежащего сортировке, мы находим индекс его первого элемента в кортеже и используем этот индекс для сравнения в порядке возрастания.
Комментарии:
1.
amp;<=/2
Может быть опущен, потому что это сортировщик по умолчаниюEnum.sort_by/3
.2. Да, я знаю, я просто хотел показать наиболее общий подход (например, в случае, если они хотят отсортировать список по убыванию.)
Ответ №2:
Для коротких списков ответ Алексея подходит, но для конкретного случая, когда у вас есть список упорядоченных ключей, я бы использовал Enum.group_by/3
для группировки объектов по ключам, а затем Enum.flat_map/2
по упорядоченным ключам, просматривая соответствующие объекты из группы. Для больших списков это означает, что вы выполняете поиск по карте O (log n) вместо поиска по списку O (n) для каждого элемента.
objects = [
{"ipnetworkaddress", [], "33.33.123.148"},
{"httpbrowsertype", [], "Mozilla"},
{"hostname", [], "example.com"}
]
ordered_keys = ["hostname", "httpbrowsertype", "ipnetworkaddress"]
grouped_objects = Enum.group_by(objects, amp;elem(amp;1, 0))
Enum.flat_map(ordered_keys, amp;grouped_objects[amp;1])