Это сохранение порядка сгруппированных элементов.
Вот пример использования стандартного group_by
:
Enum.group_by(["aa", "ab", "ac", "ba", "bb", "bc"], &String.first/1)
# %{"a" => ["aa", "ab", "ac"], "b" => ["ba", "bb", "bc"]}
Если мы удалим команду reverse
в пользовательскомреализация:
Example.no_reverse_group_by(["aa", "ab", "ac", "ba", "bb", "bc"], &String.first/1)
# %{"a" => ["ac", "ab", "aa"], "b" => ["bc", "bb", "ba"]}
Вы можете видеть внутреннее упорядочение сгруппированных элементов "ac", "ab", "aa"
, обратное исходному порядку "aa", "ab", "ac"
.
Причина в том, что Map.put(acc, key, [value | existing])
создает группы, добавляя каждый элемент value
в начало списка элементов existing
по мере их появления.Это создает группы с элементами в обратном порядке по сравнению с исходным перечисляемым.
Быстрое добавление к списку, но добавление в конец списка требует обхода всего списка.Таким образом, чтобы позволить алгоритму использовать эффективную операцию [value | existing]
prepend, и , чтобы гарантировать, что порядок элементов в группах такой же, как у исходного перечислимого, необходимо сначала обратить всплывающее перечисление.