RosettaCodeData/Task/CSV-data-manipulation/Elixir/csv-data-manipulation.elixir

52 lines
1.1 KiB
Plaintext

defmodule Csv do
defstruct header: "", data: "", separator: ","
def from_file(path) do
[header | data] = path
|> File.stream!
|> Enum.to_list
|> Enum.map(&String.trim/1)
%Csv{ header: header, data: data }
end
def sums_of_rows(csv) do
Enum.map(csv.data, fn (row) -> sum_of_row(row, csv.separator) end)
end
def sum_of_row(row, separator) do
row
|> String.split(separator)
|> Enum.map(&String.to_integer/1)
|> Enum.sum
|> to_string
end
def append_column(csv, column_header, column_data) do
header = append_to_row(csv.header, column_header, csv.separator)
data = [csv.data, column_data]
|> List.zip
|> Enum.map(fn ({ row, value }) ->
append_to_row(row, value, csv.separator)
end)
%Csv{ header: header, data: data }
end
def append_to_row(row, value, separator) do
row <> separator <> value
end
def to_file(csv, path) do
body = Enum.join([csv.header | csv.data], "\n")
File.write(path, body)
end
end
csv = Csv.from_file("in.csv")
csv
|> Csv.append_column("SUM", Csv.sums_of_rows(csv))
|> Csv.to_file("out.csv")