How to create CSV from a list of lists?

Given a list of lists, how can one create CSV file without using a third-party library?

Don’t use CSV. Most implementations I’ve seen so far have their problems and handle things very differently.

I’m not asking what to use. I’m asking - how?

Well, it totally depends on what “dialect” of CSV you need to deliver…

But a very naïve approach that should be valid CSV according to RFC 4180 as far as I glanced over it…

Also I do not do any checks, but simply assume that each sublist contains the same number of elements

data
|> Enum.map(fn row ->
  row
  |> Enum.map(fn col ->
    col = String.replace(col, "\"", "\"\"")
    "\"#{col}\""
  end)
  |> Enum.join(",")
|> Enum.join("\r\n")

But this is untested and only written down as I understood the linked RFC while only glancing over it.

3 Likes

Can you elaborate on this limitation? NimbleCSV is a highly performant and capable implementation, not sure why you’d want to reinvent that wheel.

8 Likes

I could tell you, but you’d not understand.

1 Like

Try it.

Is it because of “not invented here”?

CSV looks easy on the first glance, and therefore a lot of people have implemented it theirself, no proper standard did exist by the time beeing, so all those parsers and emitters had a different featureset.

CSV is a format that better did not exist.

3 Likes

Try us. :wink:

NimbleCSV has the same author as Elixir and the same license, so if you can use elixir, you could use it. In addition it’s code is extremely simple so it can be vetted with ease as well.

3 Likes

You could try something simple like this:

  def to_csv(data) do # data is [ [...] ]
    col_sep = ","
    row_sep = "\n"

    csv =
      for row <- data, into: "" do
        Enum.join(row, col_sep) <> row_sep
      end

    File.write(csv, "test.csv")
  end

But this fails when a comma is in the value of a field.

Noted. But I feel what @Rakakku is asking for is a simple method to generate CSVs

Bits that’s the crux… There is no simple method as CSV is specific to the receiver.

One needs to know how the receiver deals with lineendings, comas in the fields (do they need to get quoted or escaped?), How to quote or escape, etc…

I vote we pause on this thread until we hear more about the constraints from the OP.

11 Likes