Version comparison with built-in comparison keywords "3.3.15.1" > "3.3.15.0"

Hello community!

I’ve been comparing some version string binaries with the built-in comparison keywords, and the results seems about right.

I assume that the kind of data type Elixir is comparing in those cases are bitstrings, right?

Do you think this is a reliable way to compare that kind of version pattern, or am I missing something?

iex(1)> "3.0.0.0.0" > "3.3.15.0"
false
iex(2)> "3.0.0.0.0" > "3.3.15.0"
false
iex(3)> "3.3.15.0" > "3.3.15.0"  
false
iex(4)> "3.3.15.1" > "3.3.15.0"
true
iex(5)> "3.3.15.1" > "3.3.15.0"
true
iex(6)> "3.3.14.9" > "3.3.15.0"
false
iex(7)> "3.3.0.0.0.0" > "3.3.15.0"
false
iex(8)> "3.3.0.0.0.0" > "3.4"     
false

By the way, I’ve checked the Version module, but the version pattern doesn’t entirely comply with SemVer, so if we use it, we’ll need to handle our version before :frowning:

iex(1)> "1.2" > "1.15"
true

Don’t get it. It looks right, not?

For versions, I would expect version 2 to be lower than version 15 :slight_smile:

1 Like

If this is only numbers (no prereleases) then you use lists of numbers to compare. Their sort order should match what I imagine you want the versions to sort by:

[3, 14] > [3, 13, 9]
true

https://hexdocs.pm/elixir/operators.html#term-ordering

1 Like

Oh, got it. You got the point.

def string_to_version(s) do
  s
  |> String.split(".")
  |> Enum.map(&String.to_integer/1)
end

This would give you integer lists like in LostKobraKai’s post

2 Likes

How does Version do not comply with SemVer? Especially that your versions mentioned there aren’t really SemVer compatible, as have more segments than 3 (major, minor, and patch).

If you want to compare them:

def parse_ver(str) do
  str
  |> String.split(".")
  |> Enum.map(&String.to_integer/1)
end

def compare([a | as], [b | bs]) when a == b, do: compare(as, bs)
def compare([], []), do: {:ok, :equal}
def compare([a | _], [b | _]) when a > b, do: {:ok, :greater}
def compare([a | _], [b | _]) when a < b, do: {:ok, :lesser}
def compare(_, _), do: {:error, :incomparable}
1 Like

Great! This seems much better, thank you!

I meant, my version pattern doesn’t comply with SemVer, not the Version module :slight_smile: