parsing explorations
Parse Line
defmodule Y do
def parse_row(line) do
parse_row(line, line, 0)
end
def parse_row(line, <<?;, _rest::binary>>, count) do
<<city::binary-size(count), ?;, temp_value::binary>> = line
{city, parse_temperature(temp_value)}
end
def parse_row(line, <<_current_char, rest::binary>>, count) do
parse_row(line, rest, count + 1)
end
def parse_temperature(<<?-, d1, ?., d2, _::binary>>) do
-(char_to_num(d1) * 10 + char_to_num(d2))
end
def parse_temperature(<<d1, ?., d2, _::binary>>) do
char_to_num(d1) * 10 + char_to_num(d2)
end
def parse_temperature(<<?-, d1, d2, ?., d3, _::binary>>) do
-(char_to_num(d1) * 100 + char_to_num(d2) * 10 + char_to_num(d3))
end
def parse_temperature(<<d1, d2, ?., d3, _::binary>>) do
char_to_num(d1) * 100 + char_to_num(d2) * 10 + char_to_num(d3)
end
defp char_to_num(char), do: char - ?0
end
x = "Mumbai;7.2"
Y.parse_row(x)
# <<b>> = "4"
# b - ?0
<<city::binary-size(6), ?;, temp::binary>> = "Mumbai;7.2"
{city, temp}
Parse multiple lines
data = "Sacramento;16.2\nMakurdi;27.9\nTromsø;3.2"
defmodule Z do
def parse_rows(input) do
parse_rows(input, [])
end
def parse_rows("", acc), do: acc
def parse_rows(input, acc) do
{city, temp, rest} = parse_row(input)
parse_rows(rest, [{city, temp} | acc])
end
def parse_row(line) do
parse_row(line, line, 0)
end
def parse_row(line, <<?;, _rest::binary>>, count) do
<<city::binary-size(count), ?;, temp_value::binary>> = line
{temp, remaining} = parse_temperature(temp_value)
{city, temp, remaining}
end
def parse_row(line, <<_current_char, rest::binary>>, count) do
parse_row(line, rest, count + 1)
end
def parse_temperature(<<?-, d1, ?., d2, ?\n, rest::binary>>) do
{-(char_to_num(d1) * 10 + char_to_num(d2)), rest}
end
def parse_temperature(<<?-, d1, ?., d2, rest::binary>>) do
{-(char_to_num(d1) * 10 + char_to_num(d2)), rest}
end
def parse_temperature(<<d1, ?., d2, ?\n, rest::binary>>) do
{char_to_num(d1) * 10 + char_to_num(d2), rest}
end
def parse_temperature(<<d1, ?., d2, rest::binary>>) do
{char_to_num(d1) * 10 + char_to_num(d2), rest}
end
def parse_temperature(<<?-, d1, d2, ?., d3, ?\n, rest::binary>>) do
{-(char_to_num(d1) * 100 + char_to_num(d2) * 10 + char_to_num(d3)), rest}
end
def parse_temperature(<<?-, d1, d2, ?., d3, rest::binary>>) do
{-(char_to_num(d1) * 100 + char_to_num(d2) * 10 + char_to_num(d3)), rest}
end
def parse_temperature(<<d1, d2, ?., d3, ?\n, rest::binary>>) do
{char_to_num(d1) * 100 + char_to_num(d2) * 10 + char_to_num(d3), rest}
end
def parse_temperature(<<d1, d2, ?., d3, rest::binary>>) do
{char_to_num(d1) * 100 + char_to_num(d2) * 10 + char_to_num(d3), rest}
end
defp char_to_num(char), do: char - ?0
end
result = Z.parse_rows(data)
ets table types
ets_table = :ets.new(:station_stats, [:duplicate_bag, :public])
:ets.insert(ets_table, {"", %{x: 1}})
:ets.insert(ets_table, {"", %{x: 1}})
:ets.tab2list(ets_table)
[1, 2, 3, ""] |> Enum.filter(fn x -> x == "" end)