Sorting By Functions in Elixir

Sometimes we’ll want to sort a collection by something other than its natural order. For example, suppose we wanted to sort strings by their length instead of alphabetically. Here’s an example of custom sorts in Elixir.

defmodule SortingByFunctions do
  def main do
    fruits = ["peach", "banana", "kiwi"]

    # We implement a comparison function for string lengths.
    len_cmp = fn a, b -> String.length(a) <= String.length(b) end

    # Now we can call Enum.sort with this custom comparison function
    # to sort `fruits` by name length.
    sorted_fruits = Enum.sort(fruits, len_cmp)
    IO.inspect(sorted_fruits)

    # We can use the same technique to sort a list of
    # values that aren't built-in types.
    people = [
      %{name: "Jax", age: 37},
      %{name: "TJ", age: 25},
      %{name: "Alex", age: 72}
    ]

    # Sort `people` by age using Enum.sort
    sorted_people = Enum.sort(people, fn a, b -> a.age <= b.age end)
    IO.inspect(sorted_people)
  end
end

SortingByFunctions.main()

In this Elixir version, we use Enum.sort/2 which takes a collection and a sorting function. The sorting function should return true if the first argument is considered less than or equal to the second.

For the fruits list, we create a len_cmp function that compares string lengths. We then use this function with Enum.sort/2 to sort the fruits by length.

For the people list, we define a list of maps instead of structs (as Elixir doesn’t have a direct equivalent to Go’s structs). We then use Enum.sort/2 with an anonymous function that compares the age field of each map.

Note that in Elixir, we don’t need to worry about whether to use pointers for large structs, as Elixir handles memory management automatically.

When you run this program, you should see output similar to:

["kiwi", "peach", "banana"]
[%{age: 25, name: "TJ"}, %{age: 37, name: "Jax"}, %{age: 72, name: "Alex"}]

This demonstrates how to implement custom sorting in Elixir, both for built-in types and custom data structures.