Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add a delimiter to an integer in Phoenix Framework

So let's say I have a number like 123456789 and I want to convert it to a string and present it as 123,456,789 or 123 456 789 and etc. What is the best way to do that?

like image 237
NoDisplayName Avatar asked Dec 14 '22 11:12

NoDisplayName


1 Answers

I don't think there's a built in way. For general formatting you can use :io.format/2 Here's one way to do it:

123456789
|> Integer.to_char_list
|> Enum.reverse
|> Enum.chunk_every(3)
|> Enum.join(",")
|> String.reverse

# "123,456,789"

Edit: here is a solution that also works for decimals. It optionally allows setting custom separators:

defmodule Formatter do
  @doc """
  ## Examples

      iex> Formatter.format_number(1)
      "1"

      iex> Formatter.format_number(123)
      "123"

      iex> Formatter.format_number(1234)
      "1,234"

      iex> Formatter.format_number(123456789)
      "123,456,789"

      iex> Formatter.format_number(-123456789)
      "-123,456,789"

      iex> Formatter.format_number(12345.6789)
      "12,345.6789"

      iex> Formatter.format_number(-12345.6789)
      "-12,345.6789"

      iex> Formatter.format_number(123456789, thousands_separator: "")
      "123456789"

      iex> Formatter.format_number(-123456789, thousands_separator: "")
      "-123456789"

      iex> Formatter.format_number(12345.6789, thousands_separator: "")
      "12345.6789"

      iex> Formatter.format_number(-12345.6789, thousands_separator: "")
      "-12345.6789"

      iex> Formatter.format_number(123456789, decimal_separator: ",", thousands_separator: ".")
      "123.456.789"

      iex> Formatter.format_number(-123456789, decimal_separator: ",", thousands_separator: ".")
      "-123.456.789"

      iex> Formatter.format_number(12345.6789, decimal_separator: ",", thousands_separator: ".")
      "12.345,6789"

      iex> Formatter.format_number(-12345.6789, decimal_separator: ",", thousands_separator: ".")
      "-12.345,6789"
  """

  @regex ~r/(?<sign>-?)(?<int>\d+)(\.(?<frac>\d+))?/

  def format_number(number, options \\ []) do
    thousands_separator = Keyword.get(options, :thousands_separator, ",")
    parts = Regex.named_captures(@regex, to_string(number))

    formatted_int =
      parts["int"]
      |> String.graphemes
      |> Enum.reverse
      |> Enum.chunk_every(3)
      |> Enum.join(thousands_separator)
      |> String.reverse

    decimal_separator =
      if parts["frac"] == "" do
        ""
      else
        Keyword.get(options, :decimal_separator, ".")
      end

    to_string [parts["sign"], formatted_int, decimal_separator, parts["frac"]]
  end
end
like image 53
Patrick Oscity Avatar answered Jan 13 '23 06:01

Patrick Oscity