Skip to content

Instantly share code, notes, and snippets.

@mlankenau
Last active March 28, 2017 18:24
Show Gist options
  • Save mlankenau/503e7908436df8e1c4104c241848c5c0 to your computer and use it in GitHub Desktop.
Save mlankenau/503e7908436df8e1c4104c241848c5c0 to your computer and use it in GitHub Desktop.
defmodule CsvParser do
def main([file | _args]) do
{:ok, file_content} = File.read(file)
parse(file_content)
end
def parse(content) when is_binary(content) do
content
|> String.split("\n")
|> parse
end
def parse([_header | content]) do
content
|> Enum.map(&parse_line_raw/1)
|> Enum.reduce(%{sum: 0, count: 0}, fn
([a,b,c], acc) when is_number(c) ->
%{
sum: acc.sum + c,
count: acc.count+1
}
(_, acc) ->
acc
end)
end
def parse_line_raw(""), do: nil
def parse_line_raw(line) do
line
|> String.split(",")
|> Enum.map(&String.to_integer/1)
end
end
# main stuff
System.argv()
|> CsvParser.main()
|> case do
%{sum: sum, count: count} ->
IO.puts "sum: #{sum}"
IO.puts "mean: #{sum / count}"
end
############################################################################
# with stream (faster, less memory)
defmodule CsvParser do
def main([file | _args]) do
File.stream!(file)
|> Enum.map(&parse_line_raw/1)
|> Enum.reduce(%{sum: 0, count: 0}, fn
([a,b,c], acc) when is_number(c) ->
%{
sum: acc.sum + c,
count: acc.count+1
}
(_, acc) ->
acc
end)
end
def parse_line_raw(line) do
line
|> String.split(",")
|> Enum.map(&parse_col/1)
end
def parse_col(col) do
Integer.parse(col)
|> case do
:error -> 0
{i, _} -> i
end
end
end
# main stuff
System.argv()
|> CsvParser.main()
|> case do
%{sum: sum, count: count} ->
IO.puts "sum: #{sum}"
IO.puts "mean: #{sum / count}"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment