neuone

neuone

Sorting a list alphabetic then numeric

Scenario
I have a list I’m getting back where I have a mixture of letters and numbers as strings. I need the list to be sorted so it’s alphabetic first THEN numeric.

# Sample data

[
    {"1",[]},
    {"A",[]},
    {"B",[]},
    {"C",[]},
    {"D",[]},
    {"E",[]},
    {"F",[]},
    {"3",[]},
    {"4",[]},
    {"5",[]},
    {"6",[]}
]

# But I want this as the final result

[
  {"A", []},
  {"B", []},
  {"C", []},
  {"D", []},
  {"E", []},
  {"F", []},
  {"1", []},
  {"3", []},
  {"4", []}
]

My solution works
This is what I came up with and it seems to work

defmodule Foo do

  @list [
    {"1",[]},
    {"A",[]},
    {"B",[]},
    {"C",[]},
    {"D",[]},
    {"E",[]},
    {"F",[]},
    {"3",[]},
    {"4",[]},
    {"5",[]},
    {"6",[]}
  ]

  def list do
    @list
  end

  def sort_alpha_then_numeric(list) do

    numbers_alpabetic_list =
      Enum.split_with(list, fn item ->
        {key, _value} = item
      case Integer.parse(key) do
        {_, ""} -> true
        :error -> false
      end
    end)

    {number_list, alpha_list} = numbers_alpabetic_list

    # We now switch it so that the order is alpabetic then numeric
    List.flatten(alpha_list, number_list)

  end
end

So if I try this out

Foo.sort_alpha_then_numeric Foo.list
# returns
[
  {"A", []},
  {"B", []},
  {"C", []},
  {"D", []},
  {"E", []},
  {"F", []},
  {"1", []},
  {"3", []},
  {"4", []}
]

Question
It works, but would like to know if my approach can be improved and learn something about sorting. Thanks.

First Post!

LostKobrakai

LostKobrakai

Take a look at Enum.sort_by.

Most Liked

hauleth

hauleth

Using function proposed by @LostKobrakai:

def sort(list), do: Enum.sort_by(list, &comparator/2)

defp comparator(<<a, _::binary>> = ax, <<b, _::binary>> = bx) when a in ?0..?9 and b in ?0..9, do: ax <= bx
defp comparator(<<a, _::binary>>, _) when a in ?0..?9, do: true
defp comparator(ax, bx), do: ax <= bx

However it is not clear how "0a" should compare with "01". I assumed that only first character decides. Otherwise you need to expand comparator/2 function a little.

EDIT: Fixed snippet, the in operator was missing.

hauleth

hauleth

No, this is pattern matching on binaries. We are getting out first byte and then ignoring the rest _ has type binary. More info Kernel.SpecialForms.<<>>

Where Next?

Popular in Questions Top

electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

Other popular topics Top

vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 44265 214
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New

We're in Beta

About us Mission Statement