Functional programming languages such as Elixir and Erlang lets you easily manipulate lists using recursion. You can extract individual elements from a list and separate them from the rest of the elements, in an concise way. One example is a list where magnet link and other character strings are mixed together.

defmodule SortItems do

  def sort(items) when is_list(items), do: sort(items, [], [])

  defp sort([], magnets, rest), do: %{magnets: magnets, rest: rest}
  defp sort([h = "magnet:?xt=urn:btih:" <> _rst | t], magnets, rest) do
    sort(t, [h] ++ magnets, rest)
  defp sort([h|t], magnets, rest), do: sort(t, magnets, [h] ++ rest)

Let’s examine what we have here:

After defining the module name, we declare the sort/1 function, that takes a list as a parameter (enforced by the use of the is_list guard). This is the only function that will be exported, so we declare it with def instead of defp.
The second declaration of sort, whose arity is of 3, matches only if the first element, our original list of items, is empty. It shall then take the two accumulators, magnets and rest and insert them in a map to ease the access of the fields by dot-notation, for instance :

result = sort(my_items)

The third declaration might look a bit frightening.

defp sort([h = "magnet:?xt=urn:btih:" <> _rst | t], magnets, rest) do
  sort(t, [h] ++ magnets, rest)

We pattern-match over the head of the first parameter of the function.

h = "magnet:?xt=urn:btih:" <> _rst

It simply means “the first element of the first parameter starts with “magnet:?xt=urn:btih:”. We discard the rest of the list’s head by prepending a _ to it.
If it matches, then we call the sort/3 function with the tail of the list as its first parameter, and add our matching item to the magnets accumulator.

If it’s not the case, that is to say if the head of the list of items doesn’t match the “magnet:?…” pattern, then we fallback to the fourth declaration, that simply calls sort/3 while adding the head element to the rest accumulator.

The process will end when all the memebers of items are sorted either in magnets or in rest.

You can try this at home will the following data:

list = ["PHP Hammer",
        "Not a magnet link!",
        "New Programmer’s Survival Manual",
        "Mr. Foo x Mr. Bar"]


Et voilà !