I couldn't find a CSV parser so here is one

doobdargentdoobdargent Posts: 10Member
edited May 12 in Tutorials

Hi, I love CSVs, they are much more network efficient than JSON.
My use case was to parse CSV fetched from an API.
I couldn't find a parser anywhere. There is one that works with files File.get_csv_line/1, but none that work with strings.

It is not perfect, for example it does not handle escaped quotes in quoted strings but maybe it will help someone someday.
Assumptions:

  • 1st line are the headers
  • all lines have the same number of columns
  • newline is \n
func parse_csv(csv: String, delimiter:=",") -> Dictionary:
    var lines = csv.split("\n", false)
    var keys = lines[0].split(delimiter, false)
    var listDict = []

    # TODO: escaped quotes are not handled
    for lineIndex in range(1, lines.size()):
        var values := []
        var buf := ""
        var is_quoted := false

        for c in lines[lineIndex]:
            match c:
                "\"":
                    is_quoted = !is_quoted
                delimiter:
                    if is_quoted:
                        # delimiter is in a string
                        buf += c
                    else :
                        values.append(buf)
                        buf = ""
                _:
                    buf += c
        # flush the last
        values.append(buf)

        listDict.append(zip(keys, values))
    return listDict

# zip 2 arrays into a dictionary (array1 is keys, array2 is values)
func zip(array1, array2):
    assert(array1.size() == array2.size())

    var d = {}
    for i in range(array2.size()):
        d[array1[i]] = array2[i]
    return d
Sign In or Register to comment.